From c3a79f047e973b09f48332007c688a64332aa9c2 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 26 Apr 2022 19:43:29 -0700 Subject: [PATCH] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d39dc944960fa9c75ee6d3b95637ff6566bd09b5 Author: Louis Lam Date: Tue Apr 26 02:27:37 2022 +0800 Add more info commit 94ada36dfa62195b6414c999a0323eba3e74d0c8 Author: Louis Lam Date: Tue Apr 26 02:20:13 2022 +0800 Update dev guideline commit 4114f43b489d3f2fcaf37c8132334a0e6a7e9fae Author: Louis Lam Date: Tue Apr 26 02:18:14 2022 +0800 Start both dev servers in one command commit db3ef3805b1d9152820ada6ff63f3ca994e85c32 Author: Dick Tang Date: Mon Apr 25 08:25:06 2022 +0800 correct wordings for Certificate Expiry Notification (#1554) commit 751924b3355ca44d24ceede1cfdd983383426f5f Author: Louis Lam Date: Sun Apr 24 22:57:42 2022 +0800 Update to 1.15.0 commit edec1024b567a7a4bf1a69a9a591d5db366f6e7d Merge: 13a3dd9 5f9f29f Author: Louis Lam Date: Sun Apr 24 22:56:52 2022 +0800 Merge remote-tracking branch 'origin/master' commit 5f9f29f527bec1105c3bd48e0c732a747e6b035b Author: Louis Lam Date: Sun Apr 24 22:54:06 2022 +0800 Update SECURITY.md commit 13a3dd91bb99f177a703af40ba3c1073c724b33d Merge: 630bb03 d9c5a78 Author: Louis Lam Date: Sun Apr 24 22:41:29 2022 +0800 Merge remote-tracking branch 'origin/master' commit d9c5a7812c191db5db7eb65c69edcf1a9174c4bd Merge: 3582e99 484d4a2 Author: Louis Lam Date: Sun Apr 24 03:44:21 2022 +0800 Merge pull request #1544 from mathiskir/readme-improvements readme improvements commit 484d4a20abf8afc318a1307e5d7e5cb81d12a7e7 Author: Sneeex <65130981+mathiskir@users.noreply.github.com> Date: Sat Apr 23 19:29:34 2022 +0200 Small improvements commit 3582e997706b1f6751d80a16b6b43b4d1a843301 Merge: e6a1719 2197b98 Author: Louis Lam Date: Sun Apr 24 01:22:56 2022 +0800 Merge pull request #1543 from gaby/github-actions Upgrade to actions/checkout@v3 commit 2197b9844463e4924c89e53eaf84f07fa4c5bb24 Author: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Sat Apr 23 09:47:57 2022 -0400 Upgrade to actions/checkout@v3 commit e6a1719ab421f37c54385a235c1f2709e612dedd Author: Sneeex <65130981+mathiskir@users.noreply.github.com> Date: Fri Apr 22 09:59:34 2022 +0200 Change notification count (#1536) commit 7d5e7a577d1fb466d835c6343a5df9e2d0af3a1d Merge: f1c83bb d3f0bdb Author: Louis Lam Date: Fri Apr 22 14:04:00 2022 +0800 Merge pull request #1535 from Computroniks/add-jsdoc-to-contributing Added JSDoc requirement in contributing docs commit 630bb03d9c84e6885dc5db1559d41efce7d52dcd Author: Louis Lam Date: Fri Apr 22 00:47:04 2022 +0800 Update package-lock.json during release process commit f1c83bb8381c7f7698449a7d87ce6e0d3a917553 Merge: 303a226 e56ac7b Author: Louis Lam Date: Fri Apr 22 00:06:59 2022 +0800 Merge remote-tracking branch 'origin/master' commit 303a226ab76b4d6bee8b66f4b7001dab5fc12898 Author: Louis Lam Date: Fri Apr 22 00:06:46 2022 +0800 Update eslint rule commit d3f0bdb440de184b42819ae04c2119505b23225c Author: Matthew Nickson Date: Thu Apr 21 16:30:53 2022 +0100 Added JSDoc requirement in contributing docs Signed-off-by: Matthew Nickson commit e56ac7b03b44cd001f177c40e094a4eb7fbcc98d Merge: aafcbaf 4d4d04a Author: Louis Lam Date: Thu Apr 21 14:37:20 2022 +0800 Merge pull request #1530 from MrEddX/bulgarian Bulgarian commit aafcbaf098232c3bd07e964091d26b49f35d6230 Author: Louis Lam Date: Thu Apr 21 10:22:18 2022 +0800 Update README.md commit 4d4d04adbd8c0c38a7aa654fab0776720aaedf82 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Wed Apr 20 22:01:57 2022 +0300 Update bg-BG.js Some translation fixes commit f8c9472ea24b4ab706909dac8cfbd55d016ad0c3 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Wed Apr 20 21:54:57 2022 +0300 Update bg-BG.js - Updated and fixed commit 4e28ad4ac20c0d833f30e6cd90fee7bc77758d1d Merge: 06f326e 07c0801 Author: Louis Lam Date: Wed Apr 20 23:50:33 2022 +0800 Merge pull request #1524 from chakflying/fix/disable-auth-icon Fix: Handle disabled auth in user dropdown commit 06f326e49e93c7ee65e8df3f19c2df1a86557768 Merge: b326a69 8cefc96 Author: Louis Lam Date: Wed Apr 20 22:43:41 2022 +0800 Merge pull request #1527 from SiderealArt/patch-1 Update Traditional Chinese (Taiwan) translation commit 07c0801ad526b3f40480b0be10418e1274b5a312 Author: Louis Lam Date: Wed Apr 20 22:39:07 2022 +0800 Make logout button reactive, improve dropdown menu css commit 8cefc96c783f35b47011cb59b2e6df2f49153db1 Author: SiderealArt Date: Wed Apr 20 18:11:26 2022 +0800 Update Traditional Chinese (Taiwan) translation commit b326a69838236614c0b028573cf405926c8a5b48 Merge: f8f19d8 59d9891 Author: Louis Lam Date: Wed Apr 20 17:24:36 2022 +0800 Merge pull request #1523 from koen20/patch-1 Update dutch translations commit a39157628581c84b3c4186674e13a09696f7f64f Author: Nelson Chan Date: Wed Apr 20 15:09:31 2022 +0800 Chore: Add translation commit e0966e55c8b5ba97b4880e07d1d08d7382427e98 Author: Nelson Chan Date: Wed Apr 20 15:01:13 2022 +0800 Fix: Handle disabled auth in user dropdown commit 59d9891105d8312ff36da153b7d18dedf4801a20 Author: Koen Habets <6172623+koen20@users.noreply.github.com> Date: Tue Apr 19 21:17:33 2022 +0200 Update nl-NL.js commit f8f19d8dc5cd668665f4a4a6d3b46782fe556383 Merge: a3d79a9 bdc23a3 Author: Louis Lam Date: Wed Apr 20 02:57:52 2022 +0800 Merge remote-tracking branch 'origin/master' commit a3d79a93e9250dfa8d27beb40c1b1f4f8001d47e Author: Louis Lam Date: Wed Apr 20 02:56:33 2022 +0800 Update Apprise to 0.9.8 commit bdc23a3f5785196ddf86cff2cc7ddc1c84408db5 Merge: 7c13b1b 1892529 Author: Louis Lam Date: Tue Apr 19 23:48:07 2022 +0800 Merge pull request #1519 from AnnAngela/1.15.0_zh-cn Update en&zh-CN lang file with 1 new i18n entry commit 7c13b1b6cb38d1220428ce5e56fc68357c211218 Author: Louis Lam Date: Tue Apr 19 20:07:18 2022 +0800 Update to 1.15.0-beta.1 commit 10f6a3c4f53492f93d9897e9ee50372a9e3e19c1 Merge: 200fdfb cd7c2be Author: Louis Lam Date: Tue Apr 19 19:59:52 2022 +0800 Merge pull request #1229 from Computroniks/#1209-Logout-button-in-navbar Add #1209: logout button in navbar commit cd7c2beca6b7e343af9f10cbfaf92da127fb9fbc Author: Louis Lam Date: Tue Apr 19 19:46:21 2022 +0800 Update CSS for dropdown menu commit 8ee99760ec17a55a62a4968633eb0a8e61996df2 Author: Louis Lam Date: Tue Apr 19 19:41:52 2022 +0800 Minor lint commit cb55e2371876710eef222cbd1b69ff18bec18be5 Author: Louis Lam Date: Tue Apr 19 19:40:28 2022 +0800 Add $root.username commit 200fdfb808cd92a436976f62de3bbda41e75bcaa Author: Louis Lam Date: Tue Apr 19 16:46:45 2022 +0800 Merge code manually since some code moved to another file commit 29d2d95c71bf65d215a40375f620c3767b76373f Merge: 9bf3b3a b782b25 Author: Louis Lam Date: Tue Apr 19 16:43:13 2022 +0800 Merge branch '1.14.X' # Conflicts: # package.json # server/server.js commit b782b25e1796817af56b0746be8096be12411948 Author: Louis Lam Date: Tue Apr 19 16:01:08 2022 +0800 Update to 1.14.1 commit 919393cac9a46961b8d0c58423991f4c45c2d01d Author: Louis Lam Date: Tue Apr 19 15:38:59 2022 +0800 Partially change the server core into a class, remove all require("./server") #1520 commit 18925293fbf9512ed5007d4a7c769083924bcd18 Author: AnnAngela-work Date: Tue Apr 19 10:48:20 2022 +0800 Update en&zh-CN lang file with 1 new i18n entry commit 17d4003e5c620d24f453de129c0339b3ede3fa57 Author: Louis Lam Date: Tue Apr 19 00:39:49 2022 +0800 Add dropdown menu commit cefb5bb60abaf85445cd4e5c8d9a4c8d65d9f036 Merge: 8860484 9bf3b3a Author: Louis Lam Date: Mon Apr 18 20:39:24 2022 +0800 Merge branch 'master' into #1209-Logout-button-in-navbar commit 9bf3b3a0f45e20b7c4207a447111af212b7676b9 Author: Louis Lam Date: Mon Apr 18 19:15:50 2022 +0800 Update README.md commit e2c45f93bf8bab9f2c81f2c1f142dcce38ee9bde Merge: 359a490 addf75d Author: Louis Lam Date: Mon Apr 18 19:06:39 2022 +0800 Merge pull request #1509 from chakflying/feat/mqtt-optional-message Feat: Allow MQTT successMessage to be optional commit addf75daa7dacc495ba65b8eb0ee69b1627a9623 Author: Louis Lam Date: Mon Apr 18 19:05:14 2022 +0800 Fix MQTT password do not save commit 359a490ae339cdd11a8dc8731c0a93774c955fda Author: Louis Lam Date: Mon Apr 18 15:21:58 2022 +0800 Fix #1510 commit cd38dd3f68ff3412844b242131f04be345dc599e Author: Nelson Chan Date: Mon Apr 18 13:04:55 2022 +0800 Feat: Allow MQTT successMessage to be optional commit f712fe85e531159c67fcc6494d136d2bf5f3736c Author: Louis Lam Date: Mon Apr 18 12:44:32 2022 +0800 Update node-sqlite, sqlite from 3.36 to 3.38 commit c28b90feb4fd0b8457fc83a8e3ab5c70409e1f57 Author: Louis Lam Date: Sun Apr 17 20:07:32 2022 +0800 Update to 1.15.0-beta.0 commit ceba096f3ee991fa23b7e1590fa4595d86b04df1 Merge: e6a8a84 2a248ad Author: Louis Lam Date: Sun Apr 17 20:05:41 2022 +0800 Merge pull request #875 from tarun7singh/master Added MQTT Monitor type commit 2a248ad73f04454a6cc2a15bcd38f0e4232f2444 Author: Louis Lam Date: Sun Apr 17 19:56:47 2022 +0800 Change mqtt_topic from VARCHAR to TEXT commit 5fa62a888cf4bdedb2b7f33b6bba28b8627e5a8b Merge: 03bcf5c e6a8a84 Author: Louis Lam Date: Sun Apr 17 19:46:33 2022 +0800 Merge branch 'master' into mqtt2 # Conflicts: # server/database.js # server/util-server.js commit e6a8a84278677490289f3c031641b9eb47114ba4 Author: Louis Lam Date: Sun Apr 17 19:30:58 2022 +0800 Include only nessacary data in webhook commit 47c72192e115a23596e8be0d4f5d248b35dbb129 Author: Louis Lam Date: Sun Apr 17 15:43:03 2022 +0800 [eslint] Enable yoda and eqeqeq commit d71c0864478ba430cd7e8489152b9bb09bf41d50 Author: Louis Lam Date: Sun Apr 17 15:27:35 2022 +0800 Standardize array bracket spacing commit 46e1a628a73863541130a3391b3c5455b1443c8d Author: Louis Lam Date: Sun Apr 17 15:04:59 2022 +0800 Update package-lock.json commit cd3dfd3146692fa862fe18cc6f0121231cfa4afc Merge: 4e6ddc8 572f2b9 Author: Louis Lam Date: Sun Apr 17 15:04:02 2022 +0800 Merge pull request #1083 from patrickhafner/customstatuspage Custom status page commit 572f2b983827b7f49cb5a3e5db68dbee5d6d0877 Author: Louis Lam Date: Sun Apr 17 14:57:31 2022 +0800 eslint commit 8eb83394f74d661c51f235776255c94e17ab315f Author: Louis Lam Date: Sun Apr 17 14:53:13 2022 +0800 Refine UI/UX for custom css / footer text. Add switch for show/hide powered by commit 1bc01d10775bdb37c6cabbee230aee3b66662f2e Merge: 81de2ee 07c474d Author: Louis Lam Date: Sun Apr 17 13:21:41 2022 +0800 Merge branch 'master' into customstatuspage # Conflicts: # src/languages/de-DE.js commit 4e6ddc88801be544dc47af33fe173da0ad0d47db Merge: 07c474d b7aebce Author: Louis Lam Date: Sun Apr 17 01:40:43 2022 +0800 Merge pull request #1497 from MrEddX/bulgarian Bulgarian commit 07c474db0b17a158db8bc952c057fbdcafdaed84 Merge: 8d8c38b 0c40e32 Author: Louis Lam Date: Sun Apr 17 01:40:05 2022 +0800 Merge remote-tracking branch 'origin/master' commit 8d8c38b1a88b9e49b6c22d95209ac9ae5e8e37e6 Author: Louis Lam Date: Sun Apr 17 01:39:49 2022 +0800 Allow unused vars in args and fix more eslint issues commit 03bcf5c766fb9e642928f2e0448b62bfb457c107 Author: Louis Lam Date: Sun Apr 17 01:07:54 2022 +0800 Add a simple mqtt server for testing commit 136fdf376860e3d2fd5ce8d48d9a22d8aeb62c2a Author: Louis Lam Date: Sun Apr 17 01:07:36 2022 +0800 MQTT password field to password type commit e34420368b65f4bab5b759b05d1bdbee39e5bbdb Author: Louis Lam Date: Sun Apr 17 01:06:47 2022 +0800 Remove try-catch and fix username/password/port not working for mqtt commit 566133e3505fc74c84e9b04dff7a2f425ccd9287 Author: Louis Lam Date: Sat Apr 16 15:01:53 2022 +0800 Domain Name Expiry Notification for https monitor only commit 30e113755e25f6f2676508a9ca32b97a19b5daa0 Author: Louis Lam Date: Sat Apr 16 14:50:48 2022 +0800 Add HIDE_LOG and catch error if cannot subscribe topic commit 083e8355b7e7282ac283960c68c8ed9055186be8 Author: Louis Lam Date: Sat Apr 16 13:37:17 2022 +0800 Change debug to log.debug commit 64a0e1aa9b2d7ecba6112e90a66fcfbf403155f3 Author: Louis Lam Date: Sat Apr 16 13:31:40 2022 +0800 Update package-lock.json commit b1c7915bc16c6482f007b604a4160f6ee9c20d30 Merge: 0345719 2e34141 Author: Louis Lam Date: Sat Apr 16 13:28:39 2022 +0800 Merge branch 'master' into mqtt2 # Conflicts: # package-lock.json # package.json # server/database.js # server/model/monitor.js # server/server.js # src/pages/EditMonitor.vue commit b7aebceaab7af25ef14656055f00c1d30f19a424 Author: Louis Lam Date: Fri Apr 15 19:49:16 2022 +0800 Update bg-BG.js commit 0302fdbc961dae1fe23337c00866c40b006abddb Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Fri Apr 15 13:10:14 2022 +0300 Update bg-BG.js Status pages - fix commit 84a50f058fd215cc98af6036c31edfcdc5ee5959 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Fri Apr 15 13:06:22 2022 +0300 Update bg-BG.js commit 9ec652639bbca51d1c638b1e615ff4fbf38674c8 Merge: 1baee42 0c40e32 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Fri Apr 15 13:03:34 2022 +0300 Merge branch 'louislam:master' into bulgarian commit 0c40e32d7572c670e88120828ae0be2184a7430e Merge: fb00640 6f99d75 Author: Louis Lam Date: Fri Apr 15 12:34:53 2022 +0800 Merge pull request #1007 from chakflying/feat/save-chart-period Feat: Save and restore chart period commit 6f99d7577b26a45a11b5c1a3aba1fd6da1020ff0 Author: Nelson Chan Date: Fri Apr 15 03:24:58 2022 +0800 Fix: Limit saved period & clear when set to recent commit 1417b6eacf54fc70f4418629ee949c98753e7d19 Author: Nelson Chan Date: Mon Dec 6 12:05:26 2021 +0800 Feat: Save and restore chart period commit 1baee42cf52c053dcad1380f7478ec88d6cc5553 Merge: 16b61db fb00640 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Thu Apr 14 10:55:04 2022 +0300 Merge branch 'louislam:master' into bulgarian commit fb0064082ee4a301e3c1afb969e347cfd9600878 Author: Louis Lam Date: Thu Apr 14 14:29:54 2022 +0800 Change Pushdeer to PushDeer commit 93c51504f93d7828674f797f06e24d3a3fcd9b95 Author: ngc7331 Date: Wed Apr 6 08:38:48 2022 +0800 fixes: formatting and security issues Co-authored-by: Matthew Nickson commit fb059f5e91bbe8ef97cc9107b3af6996b82e4b0d Author: ngc7331 Date: Sat Apr 2 14:40:33 2022 +0800 Add support for Pushdeer notifications commit 2e3414135fbf8fbe47ee7fe1adbdfc8a20958dac Author: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com> Date: Wed Apr 13 20:17:15 2022 +0200 Update src/components/PingChart.vue Co-authored-by: Matthew Nickson commit e44699216ee21c1d052d64b27273a28771fea00f Author: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com> Date: Wed Apr 13 13:54:53 2022 +0200 Fix readability of chart hover commit fd8cba1dad83912284d56f7524815f7946e88940 Author: DX37 Date: Mon Apr 4 22:03:44 2022 +0700 nudge nodemailer strings; translate new ones commit 03dd02fd38b00fc79d15b6f0968b6f3607f93b10 Author: sovushik <30425777+sovushik@users.noreply.github.com> Date: Mon Apr 4 11:55:54 2022 +0500 Update ru-RU.js Add RU for 1.14 version commit d0b5f147e23d10f3281599ecadac39a7228ed6c2 Author: Louis Lam Date: Thu Apr 14 10:55:41 2022 +0800 Fix spelling and merge mistake commit ddf8a7a692000a9bf9d21a7b6a399a97f46c8f36 Author: Louis Lam Date: Thu Apr 14 10:43:59 2022 +0800 Fix camelCase commit bd9df09f8765db212eee5b34e309e1a058e80fa5 Author: ColdThunder11 <34985592+ColdThunder11@users.noreply.github.com> Date: Wed Feb 2 21:37:09 2022 +0800 Apply suggestions from code review, fix style Co-authored-by: Adam Stachowicz commit 4656ab3d5784139ed90ea04ec53ff38989baa54d Author: ColdThunder11 Date: Fri Jan 28 15:02:28 2022 +0800 Add OneBot notification service commit 0a5db0cecbadc01d88bb0e8dff5cc10e9b77580e Author: Louis Lam Date: Thu Apr 14 10:12:03 2022 +0800 Fix #1478 commit 60b44c2cddc37e8995b22ad8308e8e4f54bfdcce Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Fri Mar 25 07:31:26 2022 +0200 Update bg-BG.js Fixed translation. commit 16b61dba27638d17281bd60e7a81d6c982bce81f Merge: ae54d9c 2b0c184 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Wed Apr 13 21:59:53 2022 +0300 Merge branch 'louislam:master' into bulgarian commit 2b0c184a88571f61a4f62980774c1e274f7077d2 Author: Louis Lam Date: Thu Apr 14 01:21:43 2022 +0800 Update package-lock commit 2642e70fc89f279b8ff7dab8e3bae73c6ef5b79a Author: Louis Lam Date: Thu Apr 14 01:08:20 2022 +0800 Fix auto test failed due to autocrlf commit 8d0446dc38f9ad9d52999daae105216c721fa140 Author: Louis Lam Date: Thu Apr 14 00:55:54 2022 +0800 Add lint as part of test commit 3436e26ed4350b958154a115e12875e2681ddf01 Author: Louis Lam Date: Thu Apr 14 00:52:07 2022 +0800 Fix styleline, fix css format issues globally commit 649f3106e1f7b6f39d81fce9f90ab64429834553 Author: Louis Lam Date: Thu Apr 14 00:30:32 2022 +0800 Enforce semicolon, fix format globally commit 6f72ca481f0d221e003a8f1fcd7fca25ebc5e2da Merge: 670ea41 5aa747a Author: Louis Lam Date: Thu Apr 14 00:05:07 2022 +0800 Merge pull request #1479 from AnnAngela/1.14.0_translation New translation for zh-CN commit 670ea415b2dbd0fa0eadc78c19ff06b7d73f508f Merge: 17dcf6d f5d006a Author: Louis Lam Date: Thu Apr 14 00:03:53 2022 +0800 Merge pull request #1488 from c0derMo/update-german-translation updating german translation commit 17dcf6d3a2ce32958c52862baafc436d18bfe078 Merge: 4df1477 e9ce143 Author: Louis Lam Date: Wed Apr 13 23:47:08 2022 +0800 Merge pull request #910 from andreasbrett/logging introduce consistent logging commit e9ce1433cd3bf36f035924c1e23099ff5e4e61c9 Author: Louis Lam Date: Wed Apr 13 23:33:37 2022 +0800 Change log_info to log.info by making it into an object commit f5d006add8e5e02968fe926460ccc98f7477e622 Author: c0derMo Date: Wed Apr 13 14:45:41 2022 +0000 updating german translation commit 4df147786da8835d4260dde115937935bd643df1 Merge: 4053b9d 27861f0 Author: Louis Lam Date: Tue Apr 12 22:39:29 2022 +0800 Merge pull request #1483 from Alexandre-Gliganic/master Add automatic restart for docker-compose.yml commit 27861f0d146b84d381fe8d0f3b5f6986c30e3a0f Author: Alexandre Gliganic <59738710+Alexandre-Gliganic@users.noreply.github.com> Date: Tue Apr 12 16:09:01 2022 +0200 Add automatic restart docker-compose.yml commit 5aa747a3011aa6d8ccc2a2a69d9b4e6be1919926 Author: AnnAngela-work Date: Tue Apr 12 20:41:25 2022 +0800 New translation commit 81de2eedfb596031ba4a74feb9db629f7b8c4e04 Author: Louis Lam Date: Tue Apr 12 20:23:11 2022 +0800 Fix template can contain one tag only, disable vue/require-component-is eslint rule commit 4a6d7207ef31aaca52ddfac8c78d35bcdfc4c893 Merge: 3d6c52f 4053b9d Author: Louis Lam Date: Tue Apr 12 19:39:42 2022 +0800 Merge branch 'master' into customstatuspage # Conflicts: # src/languages/de-DE.js # src/languages/en.js # src/pages/StatusPage.vue commit 4053b9db1fc16e38d302114e365554ad8429996d Merge: 772d009 5ca606f Author: Louis Lam Date: Tue Apr 12 17:46:24 2022 +0800 Merge remote-tracking branch 'origin/master' commit 772d009f4356ff9422ae0d7290896f7248d0775f Merge: e3745da 1ba92d8 Author: Louis Lam Date: Tue Apr 12 17:44:04 2022 +0800 Merge branch 'master' into fluencydoc_master # Conflicts: # extra/update-version.js # server/client.js # server/server.js commit ae54d9c0110cd5c4b40cae13814bb3ba5ba220ba Merge: a7e1a78 5ca606f Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Tue Apr 12 12:37:52 2022 +0300 Merge branch 'louislam:master' into bulgarian commit 5ca606fe99dd6ddca0e664c30e174db6600d7aa8 Merge: 1ba92d8 6179f6c Author: Louis Lam Date: Tue Apr 12 17:32:52 2022 +0800 Merge pull request #1141 from marcules/issue/1138 Issue/1138 commit 6179f6c982bc49c34f1e09b7df5b4180f987dfec Merge: 0bbe157 1ba92d8 Author: Louis Lam Date: Tue Apr 12 17:15:33 2022 +0800 Merge branch 'master' into issue/1138 # Conflicts: # server/server.js commit 94770cf865959112499337a287d11473e1e65595 Author: Louis Lam Date: Tue Apr 12 16:57:22 2022 +0800 Resolve log message null reference commit 9ec29c1bc4223f1bdf4665706c01cb739451e1f3 Author: Louis Lam Date: Tue Apr 12 16:37:05 2022 +0800 Add back debug() for safe, but it is marked as deprecated commit 279e2eb3f64640645a5e8f76e672ca52f094627b Merge: 38f8a8a 1ba92d8 Author: Louis Lam Date: Tue Apr 12 16:32:14 2022 +0800 Merge branch 'master' into logging # Conflicts: # server/database.js # server/jobs.js # server/model/monitor.js # server/routers/api-router.js # server/server.js # server/socket-handlers/status-page-socket-handler.js # server/util-server.js commit 1ba92d803e8113374b46f729958c2d2824936162 Author: Louis Lam Date: Tue Apr 12 14:17:13 2022 +0800 Update to 1.14.0 commit 45ca3085b2e2e79f8a937576dc49083c3db0e6c3 Author: Louis Lam Date: Tue Apr 12 13:53:52 2022 +0800 Update CONTRIBUTING.md commit a0d1ae2cce19aaa3e2f69a4f2029c34b937f0af4 Author: Louis Lam Date: Mon Apr 11 18:02:18 2022 +0800 Better alignment of monitor list item commit f030487f7d3bab7cf859ba21d0bfca3f437f9a2a Author: Louis Lam Date: Sun Apr 10 13:46:00 2022 +0800 Fix theme color that do not apply to status page with a custom domain commit 316e65d35a9ed7fa45aeaa8d638196875416d5dc Author: Louis Lam Date: Sun Apr 10 00:46:34 2022 +0800 Update to 1.14.0-beta.2 commit df5ba02f3f995830027ffbe91aac924b27272803 Merge: 6a30dbd c9fa183 Author: Louis Lam Date: Sun Apr 10 00:42:31 2022 +0800 Merge pull request #1415 from louislam/status-page-domain [Status Page] Map domain names to status pages commit c9fa183712cd611eb455dfa4afca15dfe19c7f23 Author: Louis Lam Date: Sun Apr 10 00:25:27 2022 +0800 Manage domain names commit 0b9b5102ec94ab1bc6d6cba5ce90be52937abaa7 Author: Louis Lam Date: Sat Apr 9 17:23:22 2022 +0800 Minor commit c399984b7f32e04ce46a120c1b19086610a11383 Author: Louis Lam Date: Sat Apr 9 17:03:10 2022 +0800 Improve status page sidebar commit 0afa0be5c280eb750095206fb4096fe2a2458339 Merge: c4e74c9 6a30dbd Author: Louis Lam Date: Sat Apr 9 16:07:09 2022 +0800 Merge branch 'master' into status-page-domain # Conflicts: # server/database.js commit 6a30dbd71aa1c8bf22157546915f7876a31995e3 Author: Louis Lam Date: Sat Apr 9 15:44:50 2022 +0800 Fix Mattermost when channel is empty #1468 commit a2d9474e850b1b21bb8302bba30dfe011104200b Author: Louis Lam Date: Sat Apr 9 14:51:26 2022 +0800 Copy some keys from zh-TW to zh-HK commit 8479e772cda21754277faf2530bf24cdd7a5138a Merge: 2e50ef0 25b5ede Author: Louis Lam Date: Sat Apr 9 14:44:44 2022 +0800 Merge pull request #1463 from JohnnyChiang/update-zh-TW-translation Update zh-TW translation commit 2e50ef0e8ff8752da62c01560cb68a58cab2598f Merge: 4fb2c69 511b9dd Author: Louis Lam Date: Sat Apr 9 14:40:38 2022 +0800 Merge pull request #1450 from AnnAngela/1.14.0-zh_cn 1.14.0 translation improvement commit 4fb2c69dd1433d260bda7390e6cbd4ea21230b91 Merge: c08910a 7bbaeff Author: Louis Lam Date: Sat Apr 9 13:54:28 2022 +0800 Merge pull request #1461 from louislam/proxy-improvement Proxy Improvements commit c08910a65ca2e528b5f231cb3978388bddeecccf Author: Louis Lam Date: Fri Apr 8 19:45:39 2022 +0800 Update README.md commit 943c90425610b2bd29b60590b45770709e43551a Author: Louis Lam Date: Fri Apr 8 19:43:51 2022 +0800 Update docker-compose.yml commit 25b5edea7f5d65a65d61ea6f2750ebd954f324c6 Author: JohnnyChiang Date: Fri Apr 8 01:47:01 2022 +0800 Update zh-TW translation commit 7bbaeffd3e7bc26f938cf8394d30aa738f87d572 Author: Louis Lam Date: Fri Apr 8 00:56:56 2022 +0800 Fix reset-password (issue caused by 5027fcd320fe7fbf09d8742c8f6d5e3538e2c380) commit 008dc27f52838a1d4991e9880a71c147623b7ecd Author: Louis Lam Date: Thu Apr 7 23:03:45 2022 +0800 Reload proxy settings for monitors in the monitorList commit 5027fcd320fe7fbf09d8742c8f6d5e3538e2c380 Author: Louis Lam Date: Thu Apr 7 23:02:57 2022 +0800 Export server using an object class commit d5e68f8453650c13e8348832801b1662859ce4ed Author: Louis Lam Date: Thu Apr 7 22:53:32 2022 +0800 Export monitor list commit fcb577097bc76090e5d5ac3e0fd64b634ab7d112 Author: Louis Lam Date: Thu Apr 7 15:26:00 2022 +0800 [Proxy] Change to radio button commit 082c2dd32d286946609f26aaf44ab7419c329346 Author: Louis Lam Date: Thu Apr 7 14:45:37 2022 +0800 Remove restartMonitors() and move proxy socket events to a socket handler file commit e89356b283516a9177bee2fdb32a962fe36c3ba2 Author: Louis Lam Date: Thu Apr 7 14:37:33 2022 +0800 Show proxy option for http monitor only commit 6014b9534f1bef4313936620ff15761daeb64431 Merge: 8b45a95 ffc5bca Author: Louis Lam Date: Wed Apr 6 23:20:40 2022 +0800 Merge remote-tracking branch 'origin/master' commit 8b45a95cc3df56fafe08370a495d7ff483516176 Merge: c9deea9 02becfd Author: Louis Lam Date: Wed Apr 6 23:20:22 2022 +0800 Merge branch '1.13.X' # Conflicts: # package.json commit 02becfd1136ce3942920c567f6afb084bd4b86cb Author: Louis Lam Date: Wed Apr 6 22:54:03 2022 +0800 Update to 1.13.2 commit 8ad992eac804cb04a70119dcbda3d8cc582bcf6a Author: Louis Lam Date: Wed Apr 6 22:50:21 2022 +0800 Fix setup issue when using npm 8.6.0 commit c4e74c99430a19a4f1e36f7af9e6bd908548573c Author: Louis Lam Date: Wed Apr 6 22:43:22 2022 +0800 Render if domain matched commit fee88b32e33099c4cdbb78cfcba4413a4b2b2a4a Author: Louis Lam Date: Wed Apr 6 20:48:13 2022 +0800 Set PRAGMA synchronous = FULL commit ffc5bca51df1e4a9961cddad21a5791460faa247 Author: Louis Lam Date: Wed Apr 6 13:18:12 2022 +0800 Update required tools' links commit 511b9dd42548027d3345bca0686969684c246503 Author: AnnAngela Date: Wed Apr 6 10:31:01 2022 +0800 Update fs-rmSync.js commit e9dd64b6f0a17057e2216de0535eefa30e4c925d Author: AnnAngela Date: Wed Apr 6 10:20:57 2022 +0800 Update comments of fs-rmSync.js commit 355aec46dcbf9839324b9a151226d489b412b323 Merge: 1ecd2e4 c9deea9 Author: Louis Lam Date: Tue Apr 5 22:59:39 2022 +0800 Merge branch 'master' into status-page-domain commit c9deea9fdf8dbe0a0f96061ea75d996b47f0ce07 Merge: 70311f7 d3d1656 Author: Louis Lam Date: Tue Apr 5 22:51:33 2022 +0800 Merge pull request #1456 from Arubinu/alerta Fix "API key parameter 'undefined' is invalid" commit 70311f7a5a64ed800fad0a7c94c6f781f16c0e85 Author: Louis Lam Date: Tue Apr 5 21:27:50 2022 +0800 Add an option to enable/disable the domain name expiry notification #1364 commit 4b99160b1f4b1b92345c788fd5d18ba3d69f87b0 Author: Louis Lam Date: Tue Apr 5 19:43:23 2022 +0800 Fix "Check Update" is not checked by default commit 48d679234ae23faab65a51b7a031f1baadd96149 Author: Louis Lam Date: Tue Apr 5 19:41:29 2022 +0800 Stop bree and cloudflared while the server shutting down commit d8b32d652ffbbe3fdebc1dcb6d6b04e77909ca53 Author: Louis Lam Date: Tue Apr 5 16:44:55 2022 +0800 Update .dockerignore commit d3d1656625d033e5f64375810dca9e4f578f4229 Author: Alvin Pergens Date: Tue Apr 5 08:47:35 2022 +0200 Fix "API key parameter 'undefined' is invalid" commit 8e78e62eeedc58a4bd92dfc6637f47195356e9dd Author: AnnAngela-work Date: Mon Apr 4 17:24:22 2022 +0800 Make translation better commit 706d6cee072385a4a7a30d079326eba9727ed5a8 Author: AnnAngela Date: Mon Apr 4 11:33:02 2022 +0800 Update some components to use i18n function, update en & zh-CN translation commit 43eed45baeec59ba706be5b938a56593b1524a4a Author: AnnAngela-work Date: Sun Apr 3 22:08:24 2022 +0800 first part of zh-CN.js translation commit 19b7e2ba5ea45032159aee2833c5100987d4508d Author: AnnAngela-work Date: Sun Apr 3 22:08:03 2022 +0800 Using grep to search `$t("foo")`-like pattern to fill up the missing part of en i18n file commit 99042e6991e5fa7f83a333bfd603e00270b0c0af Author: Louis Lam Date: Sun Apr 3 22:06:39 2022 +0800 Update to 1.14.0-beta.1 commit f54084c8883bc4d83fac09fd38d721a1dac71636 Author: Louis Lam Date: Sun Apr 3 22:06:36 2022 +0800 Update beta release process commit 87d3853b8e968f55fdf0c3684586dda56c9e8118 Merge: 4738581 7fd5b61 Author: Louis Lam Date: Sat Apr 2 18:21:12 2022 +0800 Merge pull request #1348 from AnnAngela/master Detect if `fs.rmSync` is available to avoid the runtime deprecation warning commit 4738581c66da59218df821a953606bab392991e4 Author: Louis Lam Date: Sat Apr 2 11:34:00 2022 +0800 Update dependencies commit 3218a0eee80133c357a7e6995104d468372d1ed5 Merge: 87ee3c2 38e6e84 Author: Louis Lam Date: Sat Apr 2 11:26:24 2022 +0800 Merge remote-tracking branch 'origin/master' commit 87ee3c20bd88b04165cb668b9affac214c226ac9 Author: Louis Lam Date: Sat Apr 2 11:25:27 2022 +0800 Update proxy password field commit 38e6e846bfc1598505233b7093fc946ef4320a64 Author: Louis Lam Date: Fri Apr 1 23:22:15 2022 +0800 Refresh sponsor list commit 92ab2b12d0e62897e3f0f8e73c161eac75302450 Author: Louis Lam Date: Fri Apr 1 17:37:04 2022 +0800 Refresh sponsor list commit 04e3394d02bc1b3802681477262d64481ad8a3bd Merge: 8078d06 aef7719 Author: Louis Lam Date: Fri Apr 1 14:57:35 2022 +0800 Merge branch 'master' into feature/request-with-http-proxy # Conflicts: # package-lock.json # package.json # server/database.js # src/languages/en.js # src/mixins/socket.js commit f6cd2f60ca60521e9c36cd8c7e86b5723d39173f Merge: aef7719 53cea7f Author: Louis Lam Date: Fri Apr 1 14:46:56 2022 +0800 Merge pull request #1442 from BCsabaEngine/master fix: update hu lang commit 53cea7f8d3723af13fb583d24046cd9d48d46b5a Author: Balázs Csaba Date: Thu Mar 31 22:25:22 2022 +0200 fix: update hu lang commit aef77194260454c6f4e09cb72232ebce3730be57 Merge: da32a1a 514b9fb Author: Louis Lam Date: Thu Mar 31 21:32:13 2022 +0800 Merge pull request #1435 from LoaderB0T/favico feat: Favicon is updated based on satus page logo commit 514b9fb68a7177782f5bc754cae3c01e5f752975 Author: Louis Lam Date: Thu Mar 31 21:30:07 2022 +0800 Add remark commit da32a1aa19a0fe0c360bb1080b6c3b0b9792666a Author: Louis Lam Date: Thu Mar 31 16:24:28 2022 +0800 Add uk-UA to the languageList commit 7a69f9f56feee1c3358edd414114d9edc5bb51ca Merge: cb6eeae c50c20f Author: Louis Lam Date: Thu Mar 31 16:22:29 2022 +0800 Merge pull request #1438 from Deni7/master Add ukrainian translation commit c50c20faa4aa6b7022f484345402311773f72a3b Author: Louis Lam Date: Thu Mar 31 16:19:04 2022 +0800 Minor fix for uk-UA commit cb6eeaef3471ab2c166d56b33e1f4d5c7f9d6659 Author: Louis Lam Date: Thu Mar 31 16:15:34 2022 +0800 Bring connection error bar to the top commit 6674005e8b839e378e781ad60046f0d43a71d8bf Author: Louis Lam Date: Thu Mar 31 15:58:39 2022 +0800 Fix storing cloudflared token while start cloudflared commit ee3d7d8b428b82e66d6a3a2c5243307b92fb005e Author: Denis Stepanov Date: Wed Mar 30 23:21:09 2022 +0300 Add ukrainian translation commit a277cfe9e8926ea7a1805985b26b650f8f77bb35 Author: Denis Stepanov Date: Wed Mar 30 23:16:04 2022 +0300 Add ukrainian translation commit 95b0df027082a51646f5a018dfef52477e66e80a Author: Denis Stepanov Date: Wed Mar 30 23:15:28 2022 +0300 Add ukrainian translation commit f02e9c44ec450c1366f58b8acd543a228f8b51f2 Author: Louis Lam Date: Wed Mar 30 23:37:23 2022 +0800 Update to 1.14.0-beta.0 commit bb2b5cd6ac9cb85b558fba7f9dc062886cfd285c Merge: b8dea3a b72a2d3 Author: Louis Lam Date: Wed Mar 30 20:15:48 2022 +0800 Merge pull request #1427 from louislam/cloudflared Built-in ease-to-use reverse proxy with Cloudflare Tunnel commit b72a2d350fa82b279182e08af33974c6414f58cb Author: Louis Lam Date: Wed Mar 30 20:08:26 2022 +0800 Set cloudflared token from env var or arg commit 71be030733bcbc582a1305ec8700cdc31571fb64 Author: Louis Lam Date: Wed Mar 30 18:52:10 2022 +0800 Add package-lock.json and minor words commit 73b338bba6e4d5861f4a38baa31c72398c17f47a Author: Janik Schumacher Date: Wed Mar 30 12:09:38 2022 +0200 feat: Favicon is updated based on satus page logo commit 82ea896bbc340eec09adc80872762607bc38d276 Author: Louis Lam Date: Wed Mar 30 11:59:49 2022 +0800 Improve the workflow of cloudflared commit f1f4b3b377d6c00a720fee93bf4be8ed3ac675e6 Author: Louis Lam Date: Wed Mar 30 01:49:45 2022 +0800 Add reverse proxy setting page for controlling cloudflared commit a6b52b7ba633f1a8a88f16b7e64a3a51373fdff9 Merge: 44fb2a8 b8dea3a Author: Louis Lam Date: Tue Mar 29 17:42:55 2022 +0800 Merge branch 'master' into cloudflared commit b8dea3a8239f7ab53a0d4a2acd551272999d42d7 Merge: 0da6e6b 623b06e Author: Louis Lam Date: Tue Mar 29 17:39:12 2022 +0800 Merge remote-tracking branch 'origin/master' commit 0da6e6b1fb5ee7bc687d491eb3a183061d53b418 Author: Louis Lam Date: Tue Mar 29 17:38:48 2022 +0800 Some improvements commit 44fb2a88f290acec2ba750d678a6a45cee81d394 Author: Louis Lam Date: Tue Mar 29 14:48:02 2022 +0800 Add cloudflared socket handler commit 623b06e33cbf9b97b784826d0af75d9aad06d607 Merge: be88351 61d0a0a Author: Louis Lam Date: Tue Mar 29 14:14:21 2022 +0800 Merge pull request #1426 from DX37/translation-ru update russian translation commit 7d3cbff79475c7e32818e7c77a208c94c165a0dd Author: Louis Lam Date: Tue Mar 29 02:24:10 2022 +0800 [Cloudflared] Install into base docker commit 61d0a0abce8d699a44b9df3d84c70e05586a8a57 Author: DX37 Date: Mon Mar 28 21:16:13 2022 +0700 update russian translation commit 7fd5b61babcbbe6e568d7c2d8cbbe0324f52ff50 Author: AnnAngela Date: Sun Mar 27 21:12:51 2022 +0800 Inproperly conflict resolving commit 96289fe014d42d2a4147d826c2d5e262b64e9d1b Author: AnnAngela Date: Sun Mar 27 20:56:42 2022 +0800 Update index.js commit 381605aca1fe80b95684fe5fbaaa8a89343f030d Author: AnnAngela Date: Sun Mar 27 20:55:28 2022 +0800 Update update-version.js commit 742c6bcaa3969e56154a1c377f8e7699ab87a31d Merge: 88a7987 be88351 Author: AnnAngela Date: Sun Mar 27 20:54:24 2022 +0800 Merge branch 'master' into master commit 88604845e67b20293a92a8d7d5d16ca0f1048fe8 Merge: 97a5b40 be88351 Author: Matthew Nickson Date: Sun Mar 27 13:48:50 2022 +0100 Merge branch 'master' into #1209-Logout-button-in-navbar commit be88351eb3c98ec2a29e97cdb24756a4384cef65 Merge: 34a0b54 1bbd744 Author: Louis Lam Date: Sun Mar 27 11:05:50 2022 +0800 Merge pull request #1136 from chakflying/fix/prometheus-on-delete Fix: Remove prometheus metrics on delete [Test needed] commit 34a0b54b93949fbe4dce7a9a0f7edafefe57b7f5 Merge: 12237de e11ea7b Author: Louis Lam Date: Sat Mar 26 14:11:32 2022 +0800 Merge pull request #1418 from sovushik/patch-11 Update ru-RU.js commit e11ea7b0618d59dbd5bf13b020b00a4b192b6a70 Author: sovushik <30425777+sovushik@users.noreply.github.com> Date: Sat Mar 26 10:46:07 2022 +0500 Update ru-RU.js Add new string for 1.13.1 commit 12237dec6e3809404a1c84df394b232431b0f5f0 Merge: f627215 630b441 Author: Louis Lam Date: Sat Mar 26 02:09:25 2022 +0800 Merge remote-tracking branch 'origin/master' commit f6272155af39efe4330aaa9f8b8f4edf8bf46c23 Author: Louis Lam Date: Sat Mar 26 02:09:12 2022 +0800 Show page not found for invalid routes commit 630b441a2dfdf1e4cd1d1679afc4d1a06e8becb9 Merge: 623d03d 5922771 Author: Louis Lam Date: Fri Mar 25 19:00:06 2022 +0800 Merge pull request #1414 from ivanbratovic/croatian-language Update croatian (hr-HR) translation file commit 1ecd2e45d058ada5c4bffedfcaa34216b09e157e Author: Louis Lam Date: Fri Mar 25 18:59:06 2022 +0800 [Status Page] Plan to support domain names for status pages commit 59227719090cf4c37cf0128836e24defebec810a Author: Ivan Bratović Date: Fri Mar 25 11:05:51 2022 +0100 Update croatian (hr-HR) translation file Signed-off-by: Ivan Bratović commit a7e1a78ea96d3a055b205932e4223198640d3b96 Author: MrEddX <66828538+MrEddX@users.noreply.github.com> Date: Fri Mar 25 07:31:26 2022 +0200 Update bg-BG.js Fixed translation. commit 623d03dc6f3c5a1162f78ae51b536015bf2dff35 Author: Louis Lam Date: Fri Mar 25 00:03:25 2022 +0800 Fix release process commit 8078d0618d076d913feb03f78673860cfec00f44 Author: Uğur Erkan Date: Thu Nov 4 14:32:16 2021 +0300 Add socks proxy support to proxy feature - Socks proxy support implemented. - Monitor proxy agent create flow refactored and moved under proxy class. Thanks for suggestion @thomasleveil commit 9e27acb511a2449131e5abf4b8733b1a13826527 Author: Uğur Erkan Date: Thu Nov 4 13:53:54 2021 +0300 Add socks proxy agent commit 78d76512ba7928404463ee45835ade62cc9ef804 Author: Uğur Erkan Date: Sat Oct 30 20:37:15 2021 +0300 Add http and https proxy feature Added new proxy feature based on http and https proxy agents. Proxy feature works like notifications, there is many proxy could be related one proxy entry. Supported features - Proxies can activate and disable in bulk - Proxies auto enabled by default for new monitors - Proxies could be applied in bulk to current monitors - Both authenticated and anonymous proxies supported - Export and import support for proxies commit 2cc7a990ff44fc0ecd7561622e975b4312783c00 Author: Uğur Erkan Date: Sat Oct 30 17:02:29 2021 +0300 Add http and https agents commit 88a798704b793408cab3bd80077367bf863f7c54 Author: AnnAngela Date: Wed Mar 2 16:10:14 2022 +0800 Update fs-rmSync.js commit 783173fd1fa432d1c018e792e928cbf504c61f85 Author: AnnAngela-work Date: Wed Mar 2 15:48:08 2022 +0800 Add a helper function commit 281fe365c056e90107fcaf3d335565e61090f098 Author: AnnAngela-work Date: Wed Mar 2 15:23:08 2022 +0800 Mark the version as 1.11.4 in package-lock.json commit 97a5b400db0c575cbfd69552882750407ceffb03 Author: Computroniks Date: Thu Jan 27 19:45:31 2022 +0000 Added log out button to nav bar Implements Logout button in navbar #1209 Signed-off-by: Computroniks commit ca89f84b9a3f28c3e78337c181e6355e732bcdfd Author: Computroniks Date: Thu Jan 27 18:57:14 2022 +0000 Added sign-out-alt icon Signed-off-by: Computroniks commit 0345719e53ed0e7a5f7c4368584584f14e797827 Author: Tarun Singh Date: Thu Jan 20 13:20:54 2022 -0500 added cleartimeout in case client is already ended commit 22256dfcd24eb7cf8545bb5ecb8f7be3370f75c4 Author: Tarun Singh Date: Thu Jan 20 13:04:59 2022 -0500 added timeout for removing the dead loop state commit 227bbdea2f3a8d1e4d520b90b9d64031bcc70cff Author: Louis Lam Date: Thu Jan 13 12:42:34 2022 +0800 [MQTT] Try to improve error handling commit 6272514820ea126780efe873d70ee057470bacdf Author: Louis Lam Date: Thu Jan 13 11:53:08 2022 +0800 [MQTT] Use existing fields instead of creating new ones (Server) commit 1c8407a433f305a4d325667302285e27d7d4428a Author: Louis Lam Date: Thu Jan 13 11:36:55 2022 +0800 [MQTT] Use existing fields instead of creating new ones (UI) commit 32ec4beda082c8e7ab166b5ad15f618ef7871b4c Merge: 9462646 2c7a701 Author: Louis Lam Date: Thu Jan 13 11:24:45 2022 +0800 Merge branch 'master' into mqtt commit 9462646ad33eb12ad1bf14646f8999e6e690a7a4 Author: Louis Lam Date: Thu Jan 13 11:22:58 2022 +0800 Fix vulnerabilities commit 482b3f9233f6b0ac78a1c9f6e91ffad149facea5 Author: Louis Lam Date: Thu Jan 13 11:20:32 2022 +0800 Update server/util-server.js Co-authored-by: Adam Stachowicz commit 6014ed11566490e6b65e161fdbcc1b89269097af Author: Louis Lam Date: Thu Jan 13 11:19:26 2022 +0800 Fix conflict commit bfee63452d18f80c7bc788d8b08abde2633f0c34 Merge: 076d6bd fd1fce0 Author: Louis Lam Date: Thu Jan 13 11:16:58 2022 +0800 Merge branch 'master' into mqtt commit 076d6bdbb6392c4d5fcb44a8b99d199286b48e82 Merge: 4118de6 f9751d0 Author: Louis Lam Date: Thu Jan 13 11:09:16 2022 +0800 Merge branch 'master' into mqtt # Conflicts: # package-lock.json # server/database.js commit 0bbe157099996db930294893207bad3f71ea3fae Author: Marc Harnos Date: Sat Jan 8 14:36:33 2022 +0100 change parsing priority for all passed arguments update all passed args in server.js to prioritize command line, then use env.UPTIME_KUMA_ environment variables, then use the generic environment variable versions env.HOST, env.PORT, env.SSL_KEY, env.SSL_CERT and fall back to default values where applicable commit 0053a29d103d803c22a278a861e417933241fb97 Author: Marc Harnos Date: Fri Jan 7 23:16:26 2022 +0100 add validation to port value parsing only port configurations that are valid (not isNaN) after parseInt are considered to be used in port variable commit 2c8d5d28e972693af13de11bb9be5a2023eb2a8a Author: Marc Harnos Date: Fri Jan 7 23:13:38 2022 +0100 simplify host fallback logic move decision logic for freeBSD HOST environment var into temp var commit 1bbd744d0285bcb5bda457165221a3da97bc79d3 Author: Nelson Chan Date: Fri Jan 7 14:29:42 2022 +0800 Chore: Improve syntax commit 2e0e35a1ee982ae21452035648c7f707f404498c Author: Nelson Chan Date: Fri Jan 7 12:34:01 2022 +0800 Fix: Fix typo commit 1e92487f30639343b9c0bf0cf138100d5adc4b9e Author: Nelson Chan Date: Fri Jan 7 12:28:08 2022 +0800 Chore: Remove onDelete as unused commit edd2534a1ba2fbaca5b1c00db533807646d25c7a Author: Nelson Chan Date: Fri Jan 7 12:26:26 2022 +0800 Fix: Clear metrics also on stop and edit commit f6ef390c76b282474a9f96984777576a60102e0d Author: Nelson Chan Date: Fri Jan 7 11:57:24 2022 +0800 Fix: Remove Prom. metrics on delete monitor commit 3d6c52fbea26426abfbbfb9d347046168cde9254 Merge: 9ee5914 a48176b Author: Patrick Hafner Date: Sat Dec 25 04:12:05 2021 +0100 Merge branch 'master' into customstatuspage commit 9ee591417da3fb5e7ad402be97677b2f79385605 Author: Patrick Hafner Date: Sat Dec 25 04:09:41 2021 +0100 Footer HTML support, updated german translation commit 4118de6d533205e409c18e44d752e32f0a32b664 Author: Tarun Singh Date: Thu Dec 23 19:39:47 2021 -0500 fix protocol not defined bug commit 3a12e209da1207fb16b4012ec8ff01a7f08f5c0b Author: Patrick Hafner Date: Tue Dec 21 03:55:25 2021 +0100 Edit: editMode check before toggle commit 2c2a824f97f012146548a2fb7cf479b2288b78cd Author: Patrick Hafner Date: Tue Dec 21 03:31:09 2021 +0100 Add: en & de-DE language commit 931ca6a3ef05483d28cf137212afc14e1eac44a9 Author: Patrick Hafner Date: Tue Dec 21 03:27:05 2021 +0100 Add: customize status page (css and poweredby) commit d3c90df8a8e85f07c43ab00866f2d449c531a320 Author: Tarun Singh Date: Sat Dec 18 16:35:18 2021 -0500 fixed edit monitor fields empty issues commit 38f8a8ac2fa2b44930d3979cc7e52d07f6c13358 Merge: e684712 0d69b44 Author: Andreas Brett Date: Fri Dec 10 17:21:55 2021 +0100 Merge branch 'louislam:master' into logging commit e684712a77fd59222ab058f7ebb7a620f4b99ff8 Merge: dcc7856 76611ec Author: Andreas Brett Date: Tue Dec 7 18:21:56 2021 +0100 Merge branch 'louislam:master' into logging commit 5afc6a41e3afa7e003733e9dbde8d6a08f5de9d0 Author: Tarun Singh Date: Mon Dec 6 11:28:23 2021 -0500 removed https requirement for url commit dcc7856b5de42f10a04c5a4fe811a3bcec6bc99f Merge: c9b0a81 481fd3a Author: Andreas Brett Date: Sat Dec 4 09:59:10 2021 +0100 Merge branch 'louislam:master' into logging commit c9b0a81cdceb33ba665601718bc2d078a466e08a Author: Andreas Brett Date: Mon Nov 29 20:39:57 2021 +0100 Update MonitorHistory.vue commit 2f97f44086b53faf170a56d3e8de8a0ac238d7be Author: Andreas Brett Date: Mon Nov 29 20:37:44 2021 +0100 Update MonitorHistory.vue commit a13bdaac84862ca08e0eb5925129ade9fde9a6f1 Merge: ed96757 40cb22e Author: Andreas Brett Date: Mon Nov 29 20:32:42 2021 +0100 Merge branch 'master' into logging commit e3745da9863ab76c42c465dc0d14d9e6af32e246 Merge: 7179c6c 0b0fd66 Author: Fluency <93673101+fluencydoc@users.noreply.github.com> Date: Tue Nov 23 10:26:45 2021 -0800 Merge branch 'master' into master commit 35da8c78f492c533455c712fa9802085915c03e8 Author: Tarun Singh Date: Mon Nov 22 03:21:53 2021 -0500 added connection timeout and refactored code commit 7179c6cc4c4a8c33177e4d3210e5bf8542806627 Author: Fluency <93673101+fluencydoc@users.noreply.github.com> Date: Fri Nov 19 10:30:31 2021 -0800 Fix punctuation in extra/update-version.js Co-authored-by: Adam Stachowicz commit ed96757b2498daa8cf4498cd6b7780587914967b Merge: 6f2dcc6 5d3bf68 Author: Andreas Brett Date: Fri Nov 19 08:56:25 2021 +0100 Merge branch 'louislam:master' into logging commit 3306f4a8e0733642f6481b81fb016e277d126ffd Author: Tarun Singh Date: Thu Nov 18 14:03:23 2021 -0500 removed extra logging commit a2de9e4e361a141f2fd6b1271218a6b1bbd55095 Author: Fluency <93673101+fluencydoc@users.noreply.github.com> Date: Wed Nov 17 16:02:31 2021 -0800 Fixed export-function signature being scrambled. commit 3f5133d1bad4bfb5c6bcc31db38ab35403e65834 Author: Tarun Singh Date: Tue Nov 16 20:44:10 2021 -0500 Added authentication logic commit 6f2dcc6dd76f1d718a5a17ed21045b4f4da99df4 Author: Andreas Brett Date: Mon Nov 15 18:07:18 2021 +0100 using provided tsc config commit 57bed4d6726157af3518c6a4aea0113d4481125e Merge: df36a4b d5d957b Author: Andreas Brett Date: Mon Nov 15 18:04:45 2021 +0100 Merge branch 'louislam:master' into logging commit df36a4bb3c818f0672bb6d137a3327910a7ebbec Author: Andreas Brett Date: Mon Nov 15 18:02:14 2021 +0100 console.info for level "info" commit e5913c5abc01b9d5b9c3bef98274b52fe5640fd0 Author: Andreas Brett Date: Mon Nov 15 17:52:28 2021 +0100 separate log functions commit d21f7971b585d91bac8ac226ec7f3fd7b5a9a347 Author: Andreas Brett Date: Thu Nov 11 12:56:53 2021 +0100 missed settings commit bdcdf47e52938662c497f6d76e13593a06cb3f7b Author: Andreas Brett Date: Thu Nov 11 12:31:28 2021 +0100 introduce consistent logging commit f55350bebc13035e8ca54a54d84e7d8c40aec2a0 Author: Calum Bird Date: Tue Nov 9 21:24:31 2021 -0800 Generated documentation :) commit 3721d11259f432fc605ee4d85051469df34ce832 Author: Tarun Singh Date: Tue Nov 9 18:53:00 2021 -0500 changed table column names for more specifity commit 149015556b0da0c5434b665951060030e2272cbe Author: Tarun Singh Date: Thu Nov 4 22:25:29 2021 -0400 server url changes commit 2bcbeba3841df3618ee2b6675d0ffcdc90f498c3 Author: Tarun Singh Date: Thu Nov 4 22:23:02 2021 -0400 update review suggestions Co-authored-by: Adam Stachowicz commit d5d07da4eed12a86d3a1504c696abf9088ed6ba6 Author: Tarun Singh Date: Thu Nov 4 22:22:53 2021 -0400 update review suggestions Co-authored-by: Adam Stachowicz commit 2d802585ffb99d02db2e253fff3c233a5e07376c Author: Tarun Singh Date: Thu Nov 4 22:21:54 2021 -0400 Update review suggestions Co-authored-by: Adam Stachowicz commit 6828e8ef6d6235075a1ffa5a3c74287487cf2ee4 Merge: 670754b 82cde7c Author: Tarun Singh Date: Wed Nov 3 21:47:44 2021 -0400 Merge branch 'master' of https://github.com/tarun7singh/uptime-kuma commit 670754b697282f699efd7036696762807f3b61a0 Author: Tarun Singh Date: Wed Nov 3 21:46:43 2021 -0400 added MQTT monitor type --- .dockerignore | 4 + .eslintrc.js | 59 +- .github/PULL_REQUEST_TEMPLATE.md | 1 + .github/workflows/auto-test.yml | 3 +- .npmrc | 1 + .stylelintrc | 6 +- CONTRIBUTING.md | 43 +- README.md | 38 +- SECURITY.md | 9 +- babel.config.js | 4 +- config/vite.config.js | 9 +- db/patch-added-mqtt-monitor.sql | 16 + db/patch-monitor-expiry-notification.sql | 7 + db/patch-proxy.sql | 23 + db/patch-status-page-footer-css.sql | 6 + docker/alpine-base.dockerfile | 2 +- docker/debian-base.dockerfile | 16 +- docker/docker-compose.yml | 3 +- ecosystem.config.js | 10 +- extra/beta/update-version.js | 30 +- extra/close-incorrect-issue.js | 2 +- extra/download-cloudflared.js | 44 + extra/download-dist.js | 11 +- extra/fs-rmSync.js | 23 + extra/mark-as-nightly.js | 18 +- extra/press-any-key.js | 2 +- extra/reset-password.js | 8 +- extra/simple-dns-server.js | 2 +- extra/simple-mqtt-server.js | 50 + extra/update-language-files/index.js | 7 +- extra/update-version.js | 24 +- extra/update-wiki-version.js | 10 +- package-lock.json | 3544 +++++++++++++---- package.json | 32 +- server/2fa.js | 1 - server/auth.js | 12 +- server/check-version.js | 2 +- server/client.js | 36 +- server/database.js | 94 +- server/image-data-uri.js | 25 +- server/jobs.js | 16 +- server/jobs/clear-old-data.js | 2 +- server/jobs/util-worker.js | 2 +- server/model/monitor.js | 206 +- server/model/proxy.js | 21 + server/model/status_page.js | 72 + server/model/user.js | 18 +- server/modules/apicache/apicache.js | 70 + server/notification-providers/alerta.js | 8 +- server/notification-providers/aliyun-sms.js | 2 +- server/notification-providers/apprise.js | 6 +- server/notification-providers/bark.js | 37 +- server/notification-providers/clicksendsms.js | 2 +- server/notification-providers/dingding.js | 2 +- server/notification-providers/discord.js | 18 +- server/notification-providers/feishu.js | 4 +- server/notification-providers/google-chat.js | 6 +- server/notification-providers/gorush.js | 2 +- server/notification-providers/gotify.js | 2 +- server/notification-providers/line.js | 18 +- server/notification-providers/lunasea.js | 20 +- server/notification-providers/matrix.js | 6 +- server/notification-providers/mattermost.js | 15 +- .../notification-provider.js | 4 +- server/notification-providers/octopush.js | 10 +- server/notification-providers/onebot.js | 45 + server/notification-providers/promosms.js | 4 +- server/notification-providers/pushbullet.js | 18 +- server/notification-providers/pushdeer.js | 52 + server/notification-providers/pushy.js | 4 +- server/notification-providers/rocket-chat.js | 2 +- server/notification-providers/signal.js | 4 +- server/notification-providers/smtp.js | 2 +- .../notification-providers/techulus-push.js | 4 +- server/notification-providers/telegram.js | 6 +- server/notification-providers/webhook.js | 6 +- server/notification-providers/wecom.js | 4 +- server/notification.js | 36 +- server/password-hash.js | 10 +- server/ping-lite.js | 12 + server/prometheus.js | 49 +- server/proxy.js | 189 + server/rate-limiter.js | 14 +- server/routers/api-router.js | 35 +- server/server.js | 520 ++- .../cloudflared-socket-handler.js | 93 + .../socket-handlers/proxy-socket-handler.js | 54 + .../status-page-socket-handler.js | 54 +- server/uptime-kuma-server.js | 90 + server/util-server.js | 128 +- src/App.vue | 8 +- src/assets/app.scss | 20 + src/components/CertificateInfoRow.vue | 10 +- src/components/Confirm.vue | 9 +- src/components/CopyableInput.vue | 1 + src/components/CountUp.vue | 12 +- src/components/Datetime.vue | 14 +- src/components/HeartbeatBar.vue | 22 +- src/components/HiddenInput.vue | 9 +- src/components/MonitorList.vue | 21 +- src/components/NotificationDialog.vue | 3 +- src/components/PingChart.vue | 13 +- src/components/ProxyDialog.vue | 206 + src/components/PublicGroupList.vue | 2 +- src/components/Tag.vue | 2 +- src/components/ToggleSection.vue | 2 +- src/components/TwoFADialog.vue | 60 +- src/components/Uptime.vue | 16 +- src/components/notifications/Gotify.vue | 2 +- src/components/notifications/Mattermost.vue | 4 +- src/components/notifications/OneBot.vue | 34 + src/components/notifications/PushDeer.vue | 19 + src/components/notifications/Pushover.vue | 2 +- src/components/notifications/index.js | 4 +- src/components/settings/About.vue | 1 + src/components/settings/Backup.vue | 8 +- src/components/settings/General.vue | 1 - src/components/settings/MonitorHistory.vue | 12 +- src/components/settings/Proxies.vue | 48 + src/components/settings/ReverseProxy.vue | 144 + src/components/settings/Security.vue | 49 +- src/i18n.js | 5 +- src/icon.js | 8 + src/languages/bg-BG.js | 97 +- src/languages/de-DE.js | 87 +- src/languages/en.js | 105 +- src/languages/hr-HR.js | 28 +- src/languages/hu.js | 3 +- src/languages/nl-NL.js | 260 +- src/languages/ru-RU.js | 76 +- src/languages/uk-UA.js | 392 ++ src/languages/zh-CN.js | 100 +- src/languages/zh-HK.js | 178 + src/languages/zh-TW.js | 115 +- src/layouts/EmptyLayout.vue | 3 +- src/layouts/Layout.vue | 107 +- src/mixins/socket.js | 48 +- src/mixins/theme.js | 5 + src/pages/AddStatusPage.vue | 4 +- src/pages/Dashboard.vue | 4 +- src/pages/DashboardHome.vue | 1 + src/pages/EditMonitor.vue | 119 +- src/pages/Entry.vue | 34 +- src/pages/List.vue | 2 +- src/pages/ManageStatusPage.vue | 3 +- src/pages/NotFound.vue | 99 + src/pages/Settings.vue | 34 +- src/pages/StatusPage.vue | 243 +- src/router.js | 15 + src/util-frontend.js | 13 + src/util.js | 88 +- src/util.ts | 97 +- test/backend.spec.js | 2 +- test/e2e.spec.js | 1 - test/prepare-jest.js | 3 +- test/prepare-test-server.js | 3 +- 156 files changed, 7649 insertions(+), 1732 deletions(-) create mode 100644 .npmrc create mode 100644 db/patch-added-mqtt-monitor.sql create mode 100644 db/patch-monitor-expiry-notification.sql create mode 100644 db/patch-proxy.sql create mode 100644 db/patch-status-page-footer-css.sql create mode 100644 extra/download-cloudflared.js create mode 100644 extra/fs-rmSync.js create mode 100644 extra/simple-mqtt-server.js create mode 100644 server/model/proxy.js create mode 100644 server/notification-providers/onebot.js create mode 100644 server/notification-providers/pushdeer.js create mode 100644 server/proxy.js create mode 100644 server/socket-handlers/cloudflared-socket-handler.js create mode 100644 server/socket-handlers/proxy-socket-handler.js create mode 100644 server/uptime-kuma-server.js create mode 100644 src/components/ProxyDialog.vue create mode 100644 src/components/notifications/OneBot.vue create mode 100644 src/components/notifications/PushDeer.vue create mode 100644 src/components/settings/Proxies.vue create mode 100644 src/components/settings/ReverseProxy.vue create mode 100644 src/languages/uk-UA.js create mode 100644 src/pages/NotFound.vue diff --git a/.dockerignore b/.dockerignore index 4a63437a44..4ce0e13ab5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -28,6 +28,8 @@ SECURITY.md tsconfig.json .env /tmp +/babel.config.js +/ecosystem.config.js ### .gitignore content (commented rules are duplicated) @@ -42,4 +44,6 @@ dist-ssr #!/data/.gitkeep #.vscode + + ### End of .gitignore content diff --git a/.eslintrc.js b/.eslintrc.js index b0934d6d82..38a16e64d0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,4 +1,9 @@ module.exports = { + ignorePatterns: [ + "test/*", + "server/modules/apicache/*", + "src/util.js" + ], root: true, env: { browser: true, @@ -17,39 +22,47 @@ module.exports = { requireConfigFile: false, }, rules: { - "linebreak-style": ["error", "unix"], - "camelcase": ["warn", { + "yoda": "error", + eqeqeq: [ "warn", "smart" ], + "linebreak-style": [ "error", "unix" ], + "camelcase": [ "warn", { "properties": "never", "ignoreImports": true }], - // override/add rules settings here, such as: - // 'vue/no-unused-vars': 'error' - "no-unused-vars": "warn", + "no-unused-vars": [ "warn", { + "args": "none" + }], indent: [ "error", 4, { - ignoredNodes: ["TemplateLiteral"], + ignoredNodes: [ "TemplateLiteral" ], SwitchCase: 1, }, ], - quotes: ["warn", "double"], - semi: "warn", - "vue/html-indent": ["warn", 4], // default: 2 + quotes: [ "error", "double" ], + semi: "error", + "vue/html-indent": [ "error", 4 ], // default: 2 "vue/max-attributes-per-line": "off", "vue/singleline-html-element-content-newline": "off", "vue/html-self-closing": "off", + "vue/require-component-is": "off", // not allow is="style" https://github.com/vuejs/eslint-plugin-vue/issues/462#issuecomment-430234675 "vue/attribute-hyphenation": "off", // This change noNL to "no-n-l" unexpectedly - "no-multi-spaces": ["error", { + "no-multi-spaces": [ "error", { ignoreEOLComments: true, }], - "space-before-function-paren": ["error", { + "array-bracket-spacing": [ "warn", "always", { + "singleValue": true, + "objectsInArrays": false, + "arraysInArrays": false + }], + "space-before-function-paren": [ "error", { "anonymous": "always", "named": "never", "asyncArrow": "always" }], "curly": "error", - "object-curly-spacing": ["error", "always"], + "object-curly-spacing": [ "error", "always" ], "object-curly-newline": "off", "object-property-newline": "error", "comma-spacing": "error", @@ -59,37 +72,37 @@ module.exports = { "keyword-spacing": "warn", "space-infix-ops": "warn", "arrow-spacing": "warn", - "no-trailing-spaces": "warn", - "no-constant-condition": ["error", { + "no-trailing-spaces": "error", + "no-constant-condition": [ "error", { "checkLoops": false, }], "space-before-blocks": "warn", //'no-console': 'warn', "no-extra-boolean-cast": "off", - "no-multiple-empty-lines": ["warn", { + "no-multiple-empty-lines": [ "warn", { "max": 1, "maxBOF": 0, }], - "lines-between-class-members": ["warn", "always", { + "lines-between-class-members": [ "warn", "always", { exceptAfterSingleLine: true, }], "no-unneeded-ternary": "error", - "array-bracket-newline": ["error", "consistent"], - "eol-last": ["error", "always"], + "array-bracket-newline": [ "error", "consistent" ], + "eol-last": [ "error", "always" ], //'prefer-template': 'error', - "comma-dangle": ["warn", "only-multiline"], - "no-empty": ["error", { + "comma-dangle": [ "warn", "only-multiline" ], + "no-empty": [ "error", { "allowEmptyCatch": true }], "no-control-regex": "off", - "one-var": ["error", "never"], - "max-statements-per-line": ["error", { "max": 1 }] + "one-var": [ "error", "never" ], + "max-statements-per-line": [ "error", { "max": 1 }] }, "overrides": [ { "files": [ "src/languages/*.js", "src/icon.js" ], "rules": { - "comma-dangle": ["error", "always-multiline"], + "comma-dangle": [ "error", "always-multiline" ], } }, diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3dc7c8b266..fe6a66594a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -20,6 +20,7 @@ Please delete any options that are not relevant. - [ ] I ran ESLint and other linters for modified files - [ ] I have performed a self-review of my own code and tested it - [ ] I have commented my code, particularly in hard-to-understand areas + (including JSDoc for methods) - [ ] My changes generate no new warnings - [ ] My code needed automated testing. I have added them (this is optional task) diff --git a/.github/workflows/auto-test.yml b/.github/workflows/auto-test.yml index e01c02cee9..ea7fd79c94 100644 --- a/.github/workflows/auto-test.yml +++ b/.github/workflows/auto-test.yml @@ -20,7 +20,8 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v2 + - run: git config --global core.autocrlf false # Mainly for Windows + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..521a9f7c07 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +legacy-peer-deps=true diff --git a/.stylelintrc b/.stylelintrc index aad673dbcb..52301b5426 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,9 +1,13 @@ { "extends": "stylelint-config-standard", + "customSyntax": "postcss-html", "rules": { "indentation": 4, "no-descending-specificity": null, "selector-list-comma-newline-after": null, - "declaration-empty-line-before": null + "declaration-empty-line-before": null, + "alpha-value-notation": "number", + "color-function-notation": "legacy", + "shorthand-property-no-redundant-values": null } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff47b90b7e..0ee006df55 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,8 @@ My long story here: https://www.reddit.com/r/UptimeKuma/comments/t1t6or/comment/ ### Recommended Pull Request Guideline +Before deep into coding, disscussion first is preferred. Creating an empty pull request for disscussion would be recommended. + 1. Fork the project 1. Clone your fork repo to local 1. Create a new branch @@ -53,6 +55,7 @@ My long story here: https://www.reddit.com/r/UptimeKuma/comments/t1t6or/comment/ 1. Create a pull request: https://github.com/louislam/uptime-kuma/compare 1. Write a proper description 1. Click "Change to draft" +1. Discussion #### ❌ Won't Merge @@ -76,6 +79,7 @@ I personally do not like something need to learn so much and need to config so m - 4 spaces indentation - Follow `.editorconfig` - Follow ESLint +- Methods and functions should be documented with JSDoc ## Name convention @@ -86,9 +90,10 @@ I personally do not like something need to learn so much and need to config so m ## Tools - Node.js >= 14 +- NPM >= 8.5 - Git - IDE that supports ESLint and EditorConfig (I am using IntelliJ IDEA) -- A SQLite tool (SQLite Expert Personal is suggested) +- A SQLite GUI tool (SQLite Expert Personal is suggested) ## Install dependencies @@ -96,39 +101,45 @@ I personally do not like something need to learn so much and need to config so m npm ci ``` -## How to start the Backend Dev Server +## Dev Server + +(2022-04-26 Update) + +We can start the frontend dev server and the backend dev server in one command. -(2021-09-23 Update) +Port `3000` and port `3001` will be used. ```bash -npm run start-server-dev +npm run dev ``` -It binds to `0.0.0.0:3001` by default. +## Backend Server -### Backend Details +For development, it binds to `0.0.0.0:3001` by default. +For production, it binds to `0.0.0.0:3000` by default. It is mainly a socket.io app + express.js. -express.js is just used for serving the frontend built files (index.html, .js and .css etc.) +express.js is used for: +- entry point such as redirecting to a status page or the dashboard +- serving the frontend built files (index.html, .js and .css etc.) +- serving internal APIs of status page + + +### Structure in /server/ - model/ (Object model, auto mapping to the database table name) - modules/ (Modified 3rd-party modules) - notification-providers/ (individual notification logic) - routers/ (Express Routers) - socket-handler (Socket.io Handlers) -- server.js (Server main logic) - -## How to start the Frontend Dev Server +- server.js (Server entry point and main logic) -1. Set the env var `NODE_ENV` to "development". -2. Start the frontend dev server by the following command. +## Frontend Dev Server - ```bash - npm run dev - ``` +It binds to `0.0.0.0:3000` by default. Frontend dev server is used for development only. - It binds to `0.0.0.0:3000` by default. +For production, it is not used. It will be compiled to `dist` directory instead. You can use Vue.js devtools Chrome extension for debugging. diff --git a/README.md b/README.md index 3d32ac8cfe..38a1bfcb9d 100644 --- a/README.md +++ b/README.md @@ -25,19 +25,21 @@ VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollec * Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / Ping / DNS Record / Push / Steam Game Server. * Fancy, Reactive, Fast UI/UX. -* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [70+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications). +* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [90+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/tree/master/src/components/notifications). * 20 second intervals. * [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages) -* Simple Status Page +* Multiple Status Pages +* Map Status Page to Domain * Ping Chart * Certificate Info +* Proxy Support +* 2FA available ## 🔧 How to Install ### 🐳 Docker ```bash -docker volume create uptime-kuma docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1 ``` @@ -47,7 +49,10 @@ Browse to http://localhost:3001 after starting. ### 💪🏻 Non-Docker -Required Tools: Node.js >= 14, git and pm2. +Required Tools: +- [Node.js](https://nodejs.org/en/download/) >= 14 +- [Git](https://git-scm.com/downloads) +- [pm2](https://pm2.keymetrics.io/) - For run in background ```bash # Update your npm to the latest version @@ -67,11 +72,19 @@ npm install pm2 -g && pm2 install pm2-logrotate # Start Server pm2 start server/server.js --name uptime-kuma + +``` +Browse to http://localhost:3001 after starting. + +More useful PM2 Commands + +```bash # If you want to see the current console output pm2 monit -``` -Browse to http://localhost:3001 after starting. +# If you want to add it to startup +pm2 save && pm2 startup +``` ### Advanced Installation @@ -99,7 +112,7 @@ https://github.com/louislam/uptime-kuma/projects/1 Thank you so much! (GitHub Sponsors will be updated manually. OpenCollective sponsors will be updated automatically, the list will be cached by GitHub though. It may need some time to be updated) - + ## 🖼 More Screenshots @@ -144,10 +157,17 @@ https://www.reddit.com/r/UptimeKuma/ ## Contribute +### Beta Version + +Check out the latest beta release here: https://github.com/louislam/uptime-kuma/releases + +### Bug Reports / Feature Requests If you want to report a bug or request a new feature. Free feel to open a [new issue](https://github.com/louislam/uptime-kuma/issues). +### Translations If you want to translate Uptime Kuma into your language, please read: https://github.com/louislam/uptime-kuma/tree/master/src/languages -If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md +Feel free to correct my grammar in this README, source code, or wiki, as my mother language is not English and my grammar is not that great. -Unfortunately, English proofreading is needed too because my grammar is not that great. Feel free to correct my grammar in this README, source code, or wiki. +### Pull Requests +If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md diff --git a/SECURITY.md b/SECURITY.md index 3a11e88172..d043841a74 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -13,10 +13,7 @@ currently being supported with security updates. ### Uptime Kuma Versions -| Version | Supported | -| ------- | ------------------ | -| 1.9.X | :white_check_mark: | -| <= 1.8.X | ❌ | +You should use or upgrade to the latest version of Uptime Kuma. All `1.X.X` versions are upgradable to the lastest version. ### Upgradable Docker Tags @@ -24,8 +21,8 @@ currently being supported with security updates. | ------- | ------------------ | | 1 | :white_check_mark: | | 1-debian | :white_check_mark: | -| 1-alpine | :white_check_mark: | | latest | :white_check_mark: | | debian | :white_check_mark: | -| alpine | :white_check_mark: | +| 1-alpine | ⚠️ Deprecated | +| alpine | ⚠️ Deprecated | | All other tags | ❌ | diff --git a/babel.config.js b/babel.config.js index d2ad8213ab..6bb8a01a53 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,11 +1,11 @@ const config = {}; if (process.env.TEST_FRONTEND) { - config.presets = ["@babel/preset-env"]; + config.presets = [ "@babel/preset-env" ]; } if (process.env.TEST_BACKEND) { - config.plugins = ["babel-plugin-rewire"]; + config.plugins = [ "babel-plugin-rewire" ]; } module.exports = config; diff --git a/config/vite.config.js b/config/vite.config.js index a9701d4265..e2f63902d2 100644 --- a/config/vite.config.js +++ b/config/vite.config.js @@ -10,15 +10,18 @@ export default defineConfig({ plugins: [ vue(), legacy({ - targets: ["ie > 11"], - additionalLegacyPolyfills: ["regenerator-runtime/runtime"] + targets: [ "ie > 11" ], + additionalLegacyPolyfills: [ "regenerator-runtime/runtime" ] }) ], css: { postcss: { "parser": postCssScss, "map": false, - "plugins": [postcssRTLCSS] + "plugins": [ postcssRTLCSS ] } }, + server: { + open: "/" + } }); diff --git a/db/patch-added-mqtt-monitor.sql b/db/patch-added-mqtt-monitor.sql new file mode 100644 index 0000000000..02b0b09d9e --- /dev/null +++ b/db/patch-added-mqtt-monitor.sql @@ -0,0 +1,16 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +ALTER TABLE monitor + ADD mqtt_topic TEXT; + +ALTER TABLE monitor + ADD mqtt_success_message VARCHAR(255); + +ALTER TABLE monitor + ADD mqtt_username VARCHAR(255); + +ALTER TABLE monitor + ADD mqtt_password VARCHAR(255); + +COMMIT; diff --git a/db/patch-monitor-expiry-notification.sql b/db/patch-monitor-expiry-notification.sql new file mode 100644 index 0000000000..7a330014a8 --- /dev/null +++ b/db/patch-monitor-expiry-notification.sql @@ -0,0 +1,7 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +ALTER TABLE monitor + ADD expiry_notification BOOLEAN default 1; + +COMMIT; diff --git a/db/patch-proxy.sql b/db/patch-proxy.sql new file mode 100644 index 0000000000..41897b1e2b --- /dev/null +++ b/db/patch-proxy.sql @@ -0,0 +1,23 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; + +CREATE TABLE proxy ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + user_id INT NOT NULL, + protocol VARCHAR(10) NOT NULL, + host VARCHAR(255) NOT NULL, + port SMALLINT NOT NULL, + auth BOOLEAN NOT NULL, + username VARCHAR(255) NULL, + password VARCHAR(255) NULL, + active BOOLEAN NOT NULL DEFAULT 1, + 'default' BOOLEAN NOT NULL DEFAULT 0, + created_date DATETIME DEFAULT (DATETIME('now')) NOT NULL +); + +ALTER TABLE monitor ADD COLUMN proxy_id INTEGER REFERENCES proxy(id); + +CREATE INDEX proxy_id ON monitor (proxy_id); +CREATE INDEX proxy_user_id ON proxy (user_id); + +COMMIT; diff --git a/db/patch-status-page-footer-css.sql b/db/patch-status-page-footer-css.sql new file mode 100644 index 0000000000..413918f11a --- /dev/null +++ b/db/patch-status-page-footer-css.sql @@ -0,0 +1,6 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +BEGIN TRANSACTION; +ALTER TABLE status_page ADD footer_text TEXT; +ALTER TABLE status_page ADD custom_css TEXT; +ALTER TABLE status_page ADD show_powered_by BOOLEAN NOT NULL DEFAULT 1; +COMMIT; diff --git a/docker/alpine-base.dockerfile b/docker/alpine-base.dockerfile index a23c81084e..c7ce195a5d 100644 --- a/docker/alpine-base.dockerfile +++ b/docker/alpine-base.dockerfile @@ -4,5 +4,5 @@ WORKDIR /app # Install apprise, iputils for non-root ping, setpriv RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib && \ - pip3 --no-cache-dir install apprise==0.9.7 && \ + pip3 --no-cache-dir install apprise==0.9.8 && \ rm -rf /root/.cache diff --git a/docker/debian-base.dockerfile b/docker/debian-base.dockerfile index 9a8c759bbe..5502ec11fc 100644 --- a/docker/debian-base.dockerfile +++ b/docker/debian-base.dockerfile @@ -1,12 +1,26 @@ # DON'T UPDATE TO node:14-bullseye-slim, see #372. # If the image changed, the second stage image should be changed too FROM node:16-buster-slim +ARG TARGETPLATFORM + WORKDIR /app +# Install Curl # Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv # Stupid python3 and python3-pip actually install a lot of useless things into Debian, specify --no-install-recommends to skip them, make the base even smaller than alpine! RUN apt update && \ apt --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \ sqlite3 iputils-ping util-linux dumb-init && \ - pip3 --no-cache-dir install apprise==0.9.7 && \ + pip3 --no-cache-dir install apprise==0.9.8 && \ rm -rf /var/lib/apt/lists/* + +# Install cloudflared +# dpkg --add-architecture arm: cloudflared do not provide armhf, this is workaround. Read more: https://github.com/cloudflare/cloudflared/issues/583 +COPY extra/download-cloudflared.js ./extra/download-cloudflared.js +RUN node ./extra/download-cloudflared.js $TARGETPLATFORM && \ + dpkg --add-architecture arm && \ + apt update && \ + apt --yes --no-install-recommends install ./cloudflared.deb && \ + rm -rf /var/lib/apt/lists/* && \ + rm -f cloudflared.deb + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index ba22bd24eb..a6499ef9f4 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -5,9 +5,10 @@ version: '3.3' services: uptime-kuma: - image: louislam/uptime-kuma + image: louislam/uptime-kuma:1 container_name: uptime-kuma volumes: - ./uptime-kuma:/app/data ports: - 3001:3001 + restart: always diff --git a/ecosystem.config.js b/ecosystem.config.js index 5f40340071..bff3451f7d 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -1,6 +1,6 @@ module.exports = { - apps: [{ - name: "uptime-kuma", - script: "./server/server.js", - }] -} + apps: [{ + name: "uptime-kuma", + script: "./server/server.js", + }] +}; diff --git a/extra/beta/update-version.js b/extra/beta/update-version.js index aa75562d17..df2cb40a65 100644 --- a/extra/beta/update-version.js +++ b/extra/beta/update-version.js @@ -1,20 +1,14 @@ const pkg = require("../../package.json"); const fs = require("fs"); -const child_process = require("child_process"); +const childProcess = require("child_process"); const util = require("../../src/util"); util.polyfill(); -const oldVersion = pkg.version; const version = process.env.VERSION; console.log("Beta Version: " + version); -if (!oldVersion || oldVersion.includes("-beta.")) { - console.error("Error: old version should not be a beta version?"); - process.exit(1); -} - if (!version || !version.includes("-beta.")) { console.error("invalid version, beta version only"); process.exit(1); @@ -26,6 +20,10 @@ if (! exists) { // Process package.json pkg.version = version; fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); + + // Also update package-lock.json + childProcess.spawnSync("npm", [ "install" ]); + commit(version); tag(version); @@ -37,7 +35,7 @@ if (! exists) { function commit(version) { let msg = "Update to " + version; - let res = child_process.spawnSync("git", ["commit", "-m", msg, "-a"]); + let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]); let stdout = res.stdout.toString().trim(); console.log(stdout); @@ -45,15 +43,15 @@ function commit(version) { throw new Error("commit error"); } - res = child_process.spawnSync("git", ["push", "origin", "master"]); + res = childProcess.spawnSync("git", [ "push", "origin", "master" ]); console.log(res.stdout.toString().trim()); } function tag(version) { - let res = child_process.spawnSync("git", ["tag", version]); + let res = childProcess.spawnSync("git", [ "tag", version ]); console.log(res.stdout.toString().trim()); - res = child_process.spawnSync("git", ["push", "origin", version]); + res = childProcess.spawnSync("git", [ "push", "origin", version ]); console.log(res.stdout.toString().trim()); } @@ -62,15 +60,7 @@ function tagExists(version) { throw new Error("invalid version"); } - let res = child_process.spawnSync("git", ["tag", "-l", version]); + let res = childProcess.spawnSync("git", [ "tag", "-l", version ]); return res.stdout.toString().trim() === version; } - -function safeDelete(dir) { - if (fs.existsSync(dir)) { - fs.rmdirSync(dir, { - recursive: true, - }); - } -} diff --git a/extra/close-incorrect-issue.js b/extra/close-incorrect-issue.js index a15a5da37c..ae38bccc2c 100644 --- a/extra/close-incorrect-issue.js +++ b/extra/close-incorrect-issue.js @@ -29,7 +29,7 @@ const github = require("@actions/github"); owner: issue.owner, repo: issue.repo, issue_number: issue.number, - labels: ["invalid-format"] + labels: [ "invalid-format" ] }); // Add the issue closing comment diff --git a/extra/download-cloudflared.js b/extra/download-cloudflared.js new file mode 100644 index 0000000000..41519b7ca4 --- /dev/null +++ b/extra/download-cloudflared.js @@ -0,0 +1,44 @@ +// + +const http = require("https"); // or 'https' for https:// URLs +const fs = require("fs"); + +const platform = process.argv[2]; + +if (!platform) { + console.error("No platform??"); + process.exit(1); +} + +let arch = null; + +if (platform === "linux/amd64") { + arch = "amd64"; +} else if (platform === "linux/arm64") { + arch = "arm64"; +} else if (platform === "linux/arm/v7") { + arch = "arm"; +} else { + console.error("Invalid platform?? " + platform); +} + +const file = fs.createWriteStream("cloudflared.deb"); +get("https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-" + arch + ".deb"); + +function get(url) { + http.get(url, function (res) { + if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { + console.log("Redirect to " + res.headers.location); + get(res.headers.location); + } else if (res.statusCode >= 200 && res.statusCode < 300) { + res.pipe(file); + + res.on("end", function () { + console.log("Downloaded"); + }); + } else { + console.error(res.statusCode); + process.exit(1); + } + }); +} diff --git a/extra/download-dist.js b/extra/download-dist.js index dc64166c4e..b04beec7ad 100644 --- a/extra/download-dist.js +++ b/extra/download-dist.js @@ -4,6 +4,7 @@ const tar = require("tar"); const packageJSON = require("../package.json"); const fs = require("fs"); +const rmSync = require("./fs-rmSync.js"); const version = packageJSON.version; const filename = "dist.tar.gz"; @@ -11,6 +12,12 @@ const filename = "dist.tar.gz"; const url = `https://github.com/louislam/uptime-kuma/releases/download/${version}/${filename}`; download(url); +/** + * Downloads the latest version of the dist from a GitHub release. + * @param {string} url The URL to download from. + * + * Generated by Trelent + */ function download(url) { console.log(url); @@ -21,7 +28,7 @@ function download(url) { if (fs.existsSync("./dist")) { if (fs.existsSync("./dist-backup")) { - fs.rmdirSync("./dist-backup", { + rmSync("./dist-backup", { recursive: true }); } @@ -35,7 +42,7 @@ function download(url) { tarStream.on("close", () => { if (fs.existsSync("./dist-backup")) { - fs.rmdirSync("./dist-backup", { + rmSync("./dist-backup", { recursive: true }); } diff --git a/extra/fs-rmSync.js b/extra/fs-rmSync.js new file mode 100644 index 0000000000..aa45b6dc3e --- /dev/null +++ b/extra/fs-rmSync.js @@ -0,0 +1,23 @@ +const fs = require("fs"); +/** + * Detect if `fs.rmSync` is available + * to avoid the runtime deprecation warning triggered for using `fs.rmdirSync` with `{ recursive: true }` in Node.js v16, + * or the `recursive` property removing completely in the future Node.js version. + * See the link below. + * + * @todo Once we drop the support for Node.js v14 (or at least versions before v14.14.0), we can safely replace this function with `fs.rmSync`, since `fs.rmSync` was add in Node.js v14.14.0 and currently we supports all the Node.js v14 versions that include the versions before the v14.14.0, and this function have almost the same signature with `fs.rmSync`. + * @link https://nodejs.org/docs/latest-v16.x/api/deprecations.html#dep0147-fsrmdirpath--recursive-true- the deprecation infomation of `fs.rmdirSync` + * @link https://nodejs.org/docs/latest-v16.x/api/fs.html#fsrmsyncpath-options the document of `fs.rmSync` + * @param {fs.PathLike} path Valid types for path values in "fs". + * @param {fs.RmDirOptions} [options] options for `fs.rmdirSync`, if `fs.rmSync` is available and property `recursive` is true, it will automatically have property `force` with value `true`. + */ +const rmSync = (path, options) => { + if (typeof fs.rmSync === "function") { + if (options.recursive) { + options.force = true; + } + return fs.rmSync(path, options); + } + return fs.rmdirSync(path, options); +}; +module.exports = rmSync; diff --git a/extra/mark-as-nightly.js b/extra/mark-as-nightly.js index 0316596bf7..a55fd98f7e 100644 --- a/extra/mark-as-nightly.js +++ b/extra/mark-as-nightly.js @@ -4,21 +4,21 @@ const util = require("../src/util"); util.polyfill(); -const oldVersion = pkg.version -const newVersion = oldVersion + "-nightly" +const oldVersion = pkg.version; +const newVersion = oldVersion + "-nightly"; -console.log("Old Version: " + oldVersion) -console.log("New Version: " + newVersion) +console.log("Old Version: " + oldVersion); +console.log("New Version: " + newVersion); if (newVersion) { // Process package.json - pkg.version = newVersion - pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion) - pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion) - fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n") + pkg.version = newVersion; + pkg.scripts.setup = pkg.scripts.setup.replaceAll(oldVersion, newVersion); + pkg.scripts["build-docker"] = pkg.scripts["build-docker"].replaceAll(oldVersion, newVersion); + fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); // Process README.md if (fs.existsSync("README.md")) { - fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion)) + fs.writeFileSync("README.md", fs.readFileSync("README.md", "utf8").replaceAll(oldVersion, newVersion)); } } diff --git a/extra/press-any-key.js b/extra/press-any-key.js index 038cafcab0..42fc363cd9 100644 --- a/extra/press-any-key.js +++ b/extra/press-any-key.js @@ -1,4 +1,4 @@ -console.log("Publish the release note on github, then press any key to continue"); +console.log("Git Push and Publish the release note on github, then press any key to continue"); process.stdin.setRawMode(true); process.stdin.resume(); diff --git a/extra/reset-password.js b/extra/reset-password.js index 1b48dffd7c..8036a45669 100644 --- a/extra/reset-password.js +++ b/extra/reset-password.js @@ -1,11 +1,10 @@ console.log("== Uptime Kuma Reset Password Tool =="); -console.log("Loading the database"); - const Database = require("../server/database"); const { R } = require("redbean-node"); const readline = require("readline"); const { initJWTSecret } = require("../server/util-server"); +const User = require("../server/model/user"); const args = require("args-parser")(process.argv); const rl = readline.createInterface({ input: process.stdin, @@ -13,8 +12,9 @@ const rl = readline.createInterface({ }); const main = async () => { + console.log("Connecting the database"); Database.init(args); - await Database.connect(); + await Database.connect(false, false, true); try { // No need to actually reset the password for testing, just make sure no connection problem. It is ok for now. @@ -31,7 +31,7 @@ const main = async () => { let confirmPassword = await question("Confirm New Password: "); if (password === confirmPassword) { - await user.resetPassword(password); + await User.resetPassword(user.id, password); // Reset all sessions by reset jwt secret await initJWTSecret(); diff --git a/extra/simple-dns-server.js b/extra/simple-dns-server.js index 5e5745f04b..376dbdd04e 100644 --- a/extra/simple-dns-server.js +++ b/extra/simple-dns-server.js @@ -26,7 +26,7 @@ server.on("request", (request, send, rinfo) => { ttl: 300, address: "1.2.3.4" }); - } if (question.type === Packet.TYPE.AAAA) { + } else if (question.type === Packet.TYPE.AAAA) { response.answers.push({ name: question.name, type: question.type, diff --git a/extra/simple-mqtt-server.js b/extra/simple-mqtt-server.js new file mode 100644 index 0000000000..238d27726a --- /dev/null +++ b/extra/simple-mqtt-server.js @@ -0,0 +1,50 @@ +const { log } = require("../src/util"); + +const mqttUsername = "louis1"; +const mqttPassword = "!@#$LLam"; + +class SimpleMqttServer { + aedes = require("aedes")(); + server = require("net").createServer(this.aedes.handle); + + constructor(port) { + this.port = port; + } + + start() { + this.server.listen(this.port, () => { + console.log("server started and listening on port ", this.port); + }); + } +} + +let server1 = new SimpleMqttServer(10000); + +server1.aedes.authenticate = function (client, username, password, callback) { + if (username && password) { + console.log(password.toString("utf-8")); + callback(null, username === mqttUsername && password.toString("utf-8") === mqttPassword); + } else { + callback(null, false); + } +}; + +server1.aedes.on("subscribe", (subscriptions, client) => { + console.log(subscriptions); + + for (let s of subscriptions) { + if (s.topic === "test") { + server1.aedes.publish({ + topic: "test", + payload: Buffer.from("ok"), + }, (error) => { + if (error) { + log.error("mqtt_server", error); + } + }); + } + } + +}); + +server1.start(); diff --git a/extra/update-language-files/index.js b/extra/update-language-files/index.js index 7ba30cc051..e449fe347c 100644 --- a/extra/update-language-files/index.js +++ b/extra/update-language-files/index.js @@ -3,6 +3,7 @@ import fs from "fs"; import path from "path"; import util from "util"; +import rmSync from "../fs-rmSync.js"; // https://stackoverflow.com/questions/13786160/copy-folder-recursively-in-node-js /** @@ -30,7 +31,7 @@ console.log("Arguments:", process.argv); const baseLangCode = process.argv[2] || "en"; console.log("Base Lang: " + baseLangCode); if (fs.existsSync("./languages")) { - fs.rmdirSync("./languages", { recursive: true }); + rmSync("./languages", { recursive: true }); } copyRecursiveSync("../../src/languages", "./languages"); @@ -40,7 +41,7 @@ const files = fs.readdirSync("./languages"); console.log("Files:", files); for (const file of files) { - if (!file.endsWith(".js")) { + if (! file.endsWith(".js")) { console.log("Skipping " + file); continue; } @@ -82,5 +83,5 @@ for (const file of files) { fs.writeFileSync(`../../src/languages/${file}`, code); } -fs.rmdirSync("./languages", { recursive: true }); +rmSync("./languages", { recursive: true }); console.log("Done. Fixing formatting by ESLint..."); diff --git a/extra/update-version.js b/extra/update-version.js index 8f3562a5e2..d5c2ee5cac 100644 --- a/extra/update-version.js +++ b/extra/update-version.js @@ -1,6 +1,6 @@ const pkg = require("../package.json"); const fs = require("fs"); -const child_process = require("child_process"); +const childProcess = require("child_process"); const util = require("../src/util"); util.polyfill(); @@ -25,6 +25,9 @@ if (! exists) { pkg.scripts.setup = pkg.scripts.setup.replace(/(git checkout )([^\s]+)/, `$1${newVersion}`); fs.writeFileSync("package.json", JSON.stringify(pkg, null, 4) + "\n"); + // Also update package-lock.json + childProcess.spawnSync("npm", [ "install" ]); + commit(newVersion); tag(newVersion); @@ -32,10 +35,16 @@ if (! exists) { console.log("version exists"); } +/** + * Updates the version number in package.json and commits it to git. + * @param {string} version - The new version number + * + * Generated by Trelent + */ function commit(version) { let msg = "Update to " + version; - let res = child_process.spawnSync("git", ["commit", "-m", msg, "-a"]); + let res = childProcess.spawnSync("git", [ "commit", "-m", msg, "-a" ]); let stdout = res.stdout.toString().trim(); console.log(stdout); @@ -45,17 +54,22 @@ function commit(version) { } function tag(version) { - let res = child_process.spawnSync("git", ["tag", version]); + let res = childProcess.spawnSync("git", [ "tag", version ]); console.log(res.stdout.toString().trim()); } +/** + * Checks if a given version is already tagged in the git repository. + * @param {string} version - The version to check for. + * + * Generated by Trelent + */ function tagExists(version) { if (! version) { throw new Error("invalid version"); } - let res = child_process.spawnSync("git", ["tag", "-l", version]); + let res = childProcess.spawnSync("git", [ "tag", "-l", version ]); return res.stdout.toString().trim() === version; } - diff --git a/extra/update-wiki-version.js b/extra/update-wiki-version.js index 10631c3323..d0f10561f3 100644 --- a/extra/update-wiki-version.js +++ b/extra/update-wiki-version.js @@ -1,4 +1,4 @@ -const child_process = require("child_process"); +const childProcess = require("child_process"); const fs = require("fs"); const newVersion = process.env.VERSION; @@ -16,23 +16,23 @@ function updateWiki(newVersion) { safeDelete(wikiDir); - child_process.spawnSync("git", ["clone", "https://github.com/louislam/uptime-kuma.wiki.git", wikiDir]); + childProcess.spawnSync("git", [ "clone", "https://github.com/louislam/uptime-kuma.wiki.git", wikiDir ]); let content = fs.readFileSync(howToUpdateFilename).toString(); // Replace the version: https://regex101.com/r/hmj2Bc/1 content = content.replace(/(git checkout )([^\s]+)/, `$1${newVersion}`); fs.writeFileSync(howToUpdateFilename, content); - child_process.spawnSync("git", ["add", "-A"], { + childProcess.spawnSync("git", [ "add", "-A" ], { cwd: wikiDir, }); - child_process.spawnSync("git", ["commit", "-m", `Update to ${newVersion}`], { + childProcess.spawnSync("git", [ "commit", "-m", `Update to ${newVersion}` ], { cwd: wikiDir, }); console.log("Pushing to Github"); - child_process.spawnSync("git", ["push"], { + childProcess.spawnSync("git", [ "push" ], { cwd: wikiDir, }); diff --git a/package-lock.json b/package-lock.json index 1d30ce076c..9bc402c0ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "uptime-kuma", - "version": "1.12.1", + "version": "1.15.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "uptime-kuma", - "version": "1.12.1", + "version": "1.15.0", "license": "MIT", "dependencies": { "@fortawesome/fontawesome-svg-core": "~1.2.36", "@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4", "@fortawesome/vue-fontawesome": "~3.0.0-5", - "@louislam/sqlite3": "~6.0.1", + "@louislam/sqlite3": "~15.0.3", "@popperjs/core": "~2.10.2", "args-parser": "~1.3.0", "axios": "~0.26.1", @@ -32,21 +32,27 @@ "favico.js": "^0.3.10", "form-data": "~4.0.0", "http-graceful-shutdown": "~3.1.7", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", "iconv-lite": "^0.6.3", "jsonwebtoken": "~8.5.1", "jwt-decode": "^3.1.2", "limiter": "^2.1.0", + "mqtt": "^4.2.8", + "node-cloudflared-tunnel": "~1.0.9", "nodemailer": "~6.6.5", "notp": "~2.0.3", "password-hash": "~1.2.2", "postcss-rtlcss": "~3.4.1", "postcss-scss": "~4.0.3", + "prismjs": "^1.27.0", "prom-client": "~13.2.0", "prometheus-api-metrics": "~3.2.1", "qrcode": "~1.5.0", "redbean-node": "0.1.3", "socket.io": "~4.4.1", "socket.io-client": "~4.4.1", + "socks-proxy-agent": "^6.1.1", "tar": "^6.1.11", "tcp-ping": "~0.1.1", "thirty-two": "~1.0.2", @@ -59,20 +65,23 @@ "vue-i18n": "~9.1.9", "vue-image-crop-upload": "~3.0.3", "vue-multiselect": "~3.0.0-alpha.2", + "vue-prism-editor": "^2.0.0-alpha.2", "vue-qrcode": "~1.0.0", "vue-router": "~4.0.14", "vue-toastification": "~2.0.0-rc.5", "vuedraggable": "~4.1.0" }, "devDependencies": { - "@actions/github": "~5.0.0", + "@actions/github": "~5.0.1", "@babel/eslint-parser": "~7.15.8", "@babel/preset-env": "^7.15.8", "@types/bootstrap": "~5.1.9", "@vitejs/plugin-legacy": "~1.6.4", "@vitejs/plugin-vue": "~1.9.4", "@vue/compiler-sfc": "~3.2.31", + "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", + "concurrently": "^7.1.0", "core-js": "~3.18.3", "cross-env": "~7.0.3", "dns2": "~2.0.1", @@ -80,28 +89,30 @@ "eslint-plugin-vue": "~7.18.0", "jest": "~27.2.5", "jest-puppeteer": "~6.0.3", - "npm-check-updates": "^12.5.4", + "npm-check-updates": "^12.5.5", + "postcss-html": "^1.3.1", "puppeteer": "~13.1.3", "sass": "~1.42.1", "stylelint": "~14.2.0", "stylelint-config-standard": "~24.0.0", "typescript": "~4.4.4", - "vite": "~2.6.14" + "vite": "~2.6.14", + "wait-on": "^6.0.1" }, "engines": { "node": "14.* || >=16.*" } }, "node_modules/@actions/github": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", - "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.1.tgz", + "integrity": "sha512-JZGyPM9ektb8NVTTI/2gfJ9DL7Rk98tQ7OVyTlgTuaQroariRBsOnzjy0I2EarX4xUZpK88YyO503fhmjFdyAg==", "dev": true, "dependencies": { "@actions/http-client": "^1.0.11", - "@octokit/core": "^3.4.0", - "@octokit/plugin-paginate-rest": "^2.13.3", - "@octokit/plugin-rest-endpoint-methods": "^5.1.1" + "@octokit/core": "^3.6.0", + "@octokit/plugin-paginate-rest": "^2.17.0", + "@octokit/plugin-rest-endpoint-methods": "^5.13.0" } }, "node_modules/@actions/http-client": { @@ -1864,7 +1875,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "devOptional": true + "dev": true }, "node_modules/@hapi/hoek": { "version": "9.2.1", @@ -2668,19 +2679,20 @@ } }, "node_modules/@louislam/sqlite3": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-6.0.1.tgz", - "integrity": "sha512-QGLj5bjQ+O4YSPj/qxtEAArbIqW9wNzBUamlIcRbvFjFiNokItwdubqL2Gl5iX0q1mUn3Z6NoFO1rrAZ/qqlsA==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.0.3.tgz", + "integrity": "sha512-rCH6PIaa+TgBzpTRnqBKUa4H/5G2hIk5ukYK5rXxK+8hVGykRin3UMGzGejrPzIKzDnZGByIF0XD4ndi6lprRQ==", "hasInstallScript": true, "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.7", - "node-addon-api": "^3.0.0" + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "tar": "^6.1.11" }, "optionalDependencies": { - "node-gyp": "^8.4.1" + "node-gyp": "^7.1.2" }, "peerDependencies": { - "node-gyp": "8.x" + "node-gyp": "7.x" }, "peerDependenciesMeta": { "node-gyp": { @@ -2689,14 +2701,14 @@ } }, "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", - "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", "dependencies": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", + "node-fetch": "^2.6.7", "nopt": "^5.0.0", "npmlog": "^5.0.1", "rimraf": "^3.0.2", @@ -2756,31 +2768,6 @@ "node": ">= 8" } }, - "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "devOptional": true, - "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "devOptional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@npmcli/git": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.0.tgz", @@ -2802,9 +2789,9 @@ } }, "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" @@ -2857,7 +2844,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "devOptional": true, + "dev": true, "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -2896,13 +2883,17 @@ "node": "^12.13.0 || ^14.15.0 || >=16" } }, - "node_modules/@npmcli/run-script/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "node_modules/@npmcli/run-script/node_modules/@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, "engines": { - "node": ">= 10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/are-we-there-yet": { @@ -2919,18 +2910,18 @@ } }, "node_modules/@npmcli/run-script/node_modules/cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "dependencies": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -2944,22 +2935,22 @@ "unique-filename": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/cacache/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/@npmcli/run-script/node_modules/gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "dev": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -2972,36 +2963,22 @@ "wide-align": "^1.1.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/@npmcli/run-script/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -3013,22 +2990,22 @@ "ssri": "^8.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/run-script/node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/@npmcli/run-script/node_modules/minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "dependencies": { "minipass": "^3.1.6", @@ -3036,7 +3013,7 @@ "minizlib": "^2.1.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "optionalDependencies": { "encoding": "^0.1.13" @@ -3217,9 +3194,9 @@ } }, "node_modules/@sideway/address": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", - "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dev": true, "dependencies": { "@hapi/hoek": "^9.0.0" @@ -3290,12 +3267,11 @@ } }, "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "devOptional": true, + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "engines": { - "node": ">= 6" + "node": ">= 10" } }, "node_modules/@types/accepts": { @@ -3507,9 +3483,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.14.180", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.180.tgz", - "integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==" + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" }, "node_modules/@types/mime": { "version": "1.3.2", @@ -3523,9 +3499,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.22.tgz", - "integrity": "sha512-8FwbVoG4fy+ykY86XCAclKZDORttqE5/s7dyWZKLXTdv3vRy5HozBEinG5IqhvPXXzIZEcTVbuHlQEI6iuwcmw==" + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -3706,9 +3682,9 @@ } }, "node_modules/@vue/devtools-api": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.3.tgz", - "integrity": "sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==" + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz", + "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==" }, "node_modules/@vue/reactivity": { "version": "3.2.31", @@ -3829,6 +3805,68 @@ "node": ">=0.4.0" } }, + "node_modules/aedes": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/aedes/-/aedes-0.46.3.tgz", + "integrity": "sha512-i3B+H74uNRhlqcs/JdrMp7e3daz4Cwls0x4yLcfjGXz2tIwnxhF6od4m86O6yyNdz/Gg3jfY3q0sc/Cz8qzg6g==", + "dev": true, + "dependencies": { + "aedes-packet": "^2.3.1", + "aedes-persistence": "^8.1.3", + "bulk-write-stream": "^2.0.1", + "end-of-stream": "^1.4.4", + "fastfall": "^1.5.1", + "fastparallel": "^2.4.1", + "fastseries": "^2.0.0", + "hyperid": "^3.0.0", + "mqemitter": "^4.5.0", + "mqtt-packet": "^7.1.2", + "readable-stream": "^3.6.0", + "retimer": "^3.0.0", + "reusify": "^1.0.4", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/aedes-packet": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-2.3.1.tgz", + "integrity": "sha512-LqBd57uc2rui2RbjycW17dylglejG26mM4ewVXGNDnVp/SUHFVEgm7d1HTmYrnSkSCNoHti042qgcTwv/F+BtQ==", + "dev": true, + "dependencies": { + "mqtt-packet": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aedes-persistence": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-8.1.3.tgz", + "integrity": "sha512-VMCjEV+2g1TNJb/IlDEUy6SP9crT+QUhe2xc6UjyqrFNBNgTvHmOefXY7FxWrwmR2QA02vwg3+5p/JXkyg/Dkw==", + "dev": true, + "dependencies": { + "aedes-packet": "^2.3.1", + "from2": "^2.3.0", + "qlobber": "^5.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aedes/node_modules/mqtt-packet": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz", + "integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -3844,7 +3882,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "devOptional": true, + "dev": true, "dependencies": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -3858,7 +3896,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "devOptional": true, + "dev": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3871,7 +3909,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "devOptional": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4012,6 +4050,24 @@ "node": ">=0.10.0" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "optional": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4031,6 +4087,21 @@ "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.1.0.tgz", "integrity": "sha512-t7Zm5YGgEEc/3eYAicF32m/TNvL+XOeYZy9CvBUeJY/szM7frLolFylhrlZNWV/ohWhcUXygrBGjYmoQdxF4CQ==" }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, "node_modules/axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -4295,7 +4366,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -4335,6 +4405,15 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -4364,7 +4443,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -4638,7 +4716,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -4675,14 +4752,41 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.0.tgz", + "integrity": "sha512-aizhtbxgT1Udg0Fj6GssXshAVK+nxbtCV+1OtTrMNy67jffDFBY6CUBAkhO4owbleAx6fdbnWdpsmmcXydbzNw==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bulk-write-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", + "integrity": "sha512-XWOLjgHtpDasHfwM8oO4df1JoZwa7/OwTsXDzh4rUTo+9CowzeOFBZz43w+H14h1fyq+xl28tVIBrdjcjj4Gug==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } }, "node_modules/bytes": { "version": "3.1.2", @@ -4692,35 +4796,6 @@ "node": ">= 0.8" } }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "optional": true, - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -4811,9 +4886,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001319", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz", - "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==", + "version": "1.0.30001323", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz", + "integrity": "sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA==", "dev": true, "funding": [ { @@ -4826,6 +4901,12 @@ } ] }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4930,7 +5011,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6" } @@ -5029,6 +5110,15 @@ "node": ">= 0.12.0" } }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -5112,6 +5202,23 @@ "node": ">= 6" } }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/commist/node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -5127,49 +5234,188 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/concurrently": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.1.0.tgz", + "integrity": "sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==", + "dev": true, "dependencies": { - "safe-buffer": "5.2.1" + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "bin": { + "concurrently": "dist/bin/concurrently.js" }, "engines": { - "node": ">= 0.6" + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" } }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "node_modules/concurrently/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/convert-source-map": { - "version": "1.8.0", + "node_modules/concurrently/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/concurrently/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concurrently/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/concurrently/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, @@ -5230,6 +5476,12 @@ "semver": "bin/semver.js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "devOptional": true + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -5366,6 +5618,18 @@ "node": ">=0.8" } }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -5380,6 +5644,19 @@ "node": ">=10" } }, + "node_modules/date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/dayjs": { "version": "1.10.8", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.8.tgz", @@ -5535,14 +5812,11 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", "engines": { - "node": ">=0.10" + "node": ">=8" } }, "node_modules/detect-newline": { @@ -5604,6 +5878,41 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, "node_modules/domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", @@ -5625,6 +5934,35 @@ "node": ">=8" } }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -5643,6 +5981,27 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -5657,9 +6016,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.4.89", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.89.tgz", - "integrity": "sha512-z1Axg0Fu54fse8wN4fd+GAINdU5mJmLtcl6bqIcYyzNVGONcfHAeeJi88KYMQVKalhXlYuVPzKkFIU5VD0raUw==", + "version": "1.4.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", + "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", "dev": true }, "node_modules/emittery": { @@ -5696,6 +6055,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -5705,7 +6065,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -5809,6 +6168,18 @@ "node": ">=8.6" } }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -5822,7 +6193,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "devOptional": true + "dev": true }, "node_modules/error-ex": { "version": "1.3.2", @@ -6715,6 +7086,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -6750,11 +7127,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "devOptional": true }, "node_modules/fast-glob": { "version": "3.2.11", @@ -6776,7 +7162,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "devOptional": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -6796,6 +7182,28 @@ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, + "node_modules/fastfall": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q=", + "dev": true, + "dependencies": { + "reusify": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fastparallel": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4", + "xtend": "^4.0.2" + } + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -6805,6 +7213,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fastseries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-2.0.0.tgz", + "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==", + "dev": true + }, "node_modules/favico.js": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/favico.js/-/favico.js-0.3.10.tgz", @@ -7068,6 +7482,15 @@ "node": ">=0.10.0" } }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -7106,6 +7529,46 @@ "node": ">= 0.6" } }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/from2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -7250,6 +7713,15 @@ "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==" }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -7429,6 +7901,29 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "devOptional": true }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "optional": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -7489,6 +7984,15 @@ "node": ">=8" } }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -7502,15 +8006,24 @@ } }, "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", + "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "lru-cache": "^7.5.1" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/html-encoding-sniffer": { @@ -7540,11 +8053,30 @@ "node": ">=8" } }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "devOptional": true + "dev": true }, "node_modules/http-errors": { "version": "1.8.1", @@ -7573,12 +8105,11 @@ } }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "devOptional": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dependencies": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" }, @@ -7586,6 +8117,21 @@ "node": ">= 6" } }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -7619,11 +8165,21 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "devOptional": true, + "dev": true, "dependencies": { "ms": "^2.0.0" } }, + "node_modules/hyperid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hyperid/-/hyperid-3.0.1.tgz", + "integrity": "sha512-I+tl7TS5nsoVhkxqX1rS3Qmqlq44eoPUcgPthW8v3IW8CvWL7lwtd6HQbkDUMrBKJTG0vgEaRsjT35imW/D+9Q==", + "dev": true, + "dependencies": { + "uuid": "^8.3.2", + "uuid-parse": "^1.1.0" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -7639,7 +8195,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -7724,7 +8279,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.8.19" } @@ -7733,7 +8288,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -7742,7 +8297,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "devOptional": true + "dev": true }, "node_modules/inflight": { "version": "1.0.6", @@ -7775,8 +8330,7 @@ "node_modules/ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "devOptional": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "node_modules/ipaddr.js": { "version": "1.9.1", @@ -7936,7 +8490,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "devOptional": true + "dev": true }, "node_modules/is-npm": { "version": "5.0.0", @@ -8042,7 +8596,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "devOptional": true }, "node_modules/is-valid-path": { "version": "0.1.1", @@ -8070,6 +8624,12 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "devOptional": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -8085,6 +8645,12 @@ "node": ">=0.10.0" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -10068,6 +10634,11 @@ "@sideway/pinpoint": "^2.0.0" } }, + "node_modules/js-sdsl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-2.1.4.tgz", + "integrity": "sha512-/Ew+CJWHNddr7sjwgxaVeIORIH4AMVC9dy0hPf540ZGMVgS9d3ajwuVdyhDt6/QUvT8ATjR3yuYBKsS79F+H4A==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10087,6 +10658,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -10133,6 +10710,15 @@ } } }, + "node_modules/jsdom/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsdom/node_modules/acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -10159,6 +10745,20 @@ "node": ">= 6" } }, + "node_modules/jsdom/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -10192,11 +10792,17 @@ "jju": "^1.1.0" } }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "optional": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "devOptional": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -10204,6 +10810,12 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, "node_modules/json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -10260,6 +10872,21 @@ "semver": "bin/semver" } }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "optional": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/just-performance": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/just-performance/-/just-performance-4.3.0.tgz", @@ -10692,33 +11319,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "optional": true, - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -10784,6 +11384,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/meow/node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -10874,13 +11486,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" @@ -10957,8 +11569,7 @@ "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/minimist-options": { "version": "4.1.0", @@ -10998,7 +11609,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11006,28 +11617,11 @@ "node": ">= 8" } }, - "node_modules/minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "optional": true, - "dependencies": { - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "encoding": "^0.1.12" - } - }, "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11049,7 +11643,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11061,7 +11655,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -11120,6 +11714,61 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "node_modules/mqemitter": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-4.5.0.tgz", + "integrity": "sha512-Mp/zytFeIv6piJQkEKnncHcP4R/ErJc5C7dfonkhkNUT2LA/nTayrfNxbipp3M5iCJUTQSUtzfQAQA3XVcKz6w==", + "dev": true, + "dependencies": { + "fastparallel": "^2.3.0", + "qlobber": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -11131,9 +11780,9 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -11156,9 +11805,17 @@ } }, "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node_modules/node-cloudflared-tunnel": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/node-cloudflared-tunnel/-/node-cloudflared-tunnel-1.0.9.tgz", + "integrity": "sha512-d0mhIM5P2ldE2yHChehC6EvnpFCkifWRzWrW81gVWdcCWqNcyISXuDdOYzRW5mwmjWuT6WNtLJoGQ84uqS4EmA==", + "dependencies": { + "command-exists": "^1.2.9" + } }, "node_modules/node-fetch": { "version": "2.6.7", @@ -11199,20 +11856,20 @@ } }, "node_modules/node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "optional": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", + "graceful-fs": "^4.2.3", "nopt": "^5.0.0", - "npmlog": "^6.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", + "semver": "^7.3.2", + "tar": "^6.0.2", "which": "^2.0.2" }, "bin": { @@ -11222,57 +11879,96 @@ "node": ">= 10.12.0" } }, + "node_modules/node-gyp/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-gyp/node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", - "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "optional": true, "dependencies": { "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "readable-stream": "^2.0.6" } }, "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "optional": true, "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/node-gyp/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": ">=0.10.0" } }, "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", - "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "optional": true, "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/node-gyp/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, + "node_modules/node-gyp/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, "node_modules/node-gyp/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "optional": true, "dependencies": { "lru-cache": "^6.0.0" @@ -11284,6 +11980,41 @@ "node": ">=10" } }, + "node_modules/node-gyp/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/node-gyp/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-gyp/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -11333,27 +12064,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16" } }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "dependencies": { - "lru-cache": "^7.5.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/normalize-package-data/node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -11411,9 +12121,9 @@ } }, "node_modules/npm-check-updates": { - "version": "12.5.4", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.4.tgz", - "integrity": "sha512-4+27zaTdieWgvPLaCZ/A6Q2WC1cYVcrc2SqVmLFYgkWBrKw1QkwpeV16FSvkFGZr3OdFyr7Dpjw8JRn4H2QxFw==", + "version": "12.5.5", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.5.tgz", + "integrity": "sha512-7LH6KN6F1fZMtY4zNYAQPpJU1ToxZ6sSCxk948vrLIz97aNqmPLSX72MrmbOWwpyBgLCPbFJWY/k3zE18pmxfw==", "dev": true, "dependencies": { "chalk": "^4.1.2", @@ -11425,7 +12135,7 @@ "fp-and-or": "^0.1.3", "get-stdin": "^8.0.0", "globby": "^11.0.4", - "hosted-git-info": "^4.1.0", + "hosted-git-info": "^5.0.0", "json-parse-helpfulerror": "^1.0.3", "jsonlines": "^0.1.1", "libnpmconfig": "^1.2.1", @@ -11664,38 +12374,17 @@ "dev": true }, "node_modules/npm-package-arg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.1.tgz", - "integrity": "sha512-Xs9wznfEAmZAR61qsYH3iN24V/qMYYkvAR5CRQNMvC6PjN2fHtO8y9XP/xdp5K+Icx+u1wMBMgWRPCmAEChSog==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.2.tgz", + "integrity": "sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g==", "dev": true, "dependencies": { "hosted-git-info": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm-package-arg/node_modules/hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "dependencies": { - "lru-cache": "^7.5.1" + "validate-npm-package-name": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm-package-arg/node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true, - "engines": { - "node": ">=12" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-package-arg/node_modules/semver": { @@ -11762,45 +12451,49 @@ } }, "node_modules/npm-registry-fetch": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.0.1.tgz", - "integrity": "sha512-Ak+LXVtSrCLOdscFW/apUw67OPNph8waHsPKM9UOJosL7i59EF5XoSWQMEsXEOeifM9Bb4/2+WrQC4t/pd8DGg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.1.0.tgz", + "integrity": "sha512-TIYL5X8CcwDhbFMXFDShNcpG6OMCYK6VzvSr6MUWP20tCU2DJ4ao2qQg3DT+3Pet8mO6/cgbZpon4LMh3duYLg==", "dev": true, "dependencies": { - "make-fetch-happen": "^10.0.3", + "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", - "minipass-fetch": "^2.0.1", + "minipass-fetch": "^2.0.3", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.0", + "npm-package-arg": "^9.0.1", "proc-log": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/npm-registry-fetch/node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "node_modules/npm-registry-fetch/node_modules/@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, "engines": { - "node": ">= 10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch/node_modules/cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "dependencies": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -11814,45 +12507,31 @@ "unique-filename": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/npm-registry-fetch/node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "dependencies": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -11864,13 +12543,13 @@ "ssri": "^8.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "dependencies": { "minipass": "^3.1.6", @@ -11878,12 +12557,39 @@ "minizlib": "^2.1.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "optionalDependencies": { "encoding": "^0.1.13" } }, + "node_modules/npm-registry-fetch/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-registry-fetch/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -11907,6 +12613,24 @@ "set-blocking": "^2.0.0" } }, + "node_modules/number-allocator": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.10.tgz", + "integrity": "sha512-K4AvNGKo9lP6HqsZyfSr9KDaqnwFzW203inhQEOwFrmFaYevpdX4VNwdOLk197aHujzbT//z6pCBrCOUYSM5iw==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "^2.1.2" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/numbered": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", @@ -11918,6 +12642,15 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -12059,7 +12792,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "devOptional": true, + "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -12153,19 +12886,32 @@ "node": "^12.13.0 || ^14.15.0 || >=16" } }, + "node_modules/pacote/node_modules/@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/pacote/node_modules/cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "dependencies": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -12179,18 +12925,45 @@ "unique-filename": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/pacote/node_modules/lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true, "engines": { "node": ">=12" } }, + "node_modules/pacote/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pacote/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -12327,6 +13100,12 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, "node_modules/pg-connection-string": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", @@ -12409,6 +13188,20 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-html": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.3.1.tgz", + "integrity": "sha512-SJ7iRw+IngyZv3Z9lChlZU30a9y9MZjZZcoUJmx0T/nKE9S+hetJ8fAv/MRu4bPnGDsXhVlaFs5+umpK3yaaQQ==", + "dev": true, + "dependencies": { + "htmlparser2": "^7.1.2", + "postcss": "^8.4.0", + "postcss-safe-parser": "^6.0.0" + }, + "engines": { + "node": "^12 || >=14" + } + }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -12467,9 +13260,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", - "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -12529,15 +13322,28 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "engines": { + "node": ">=6" + } + }, "node_modules/proc-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.0.tgz", - "integrity": "sha512-I/35MfCX2H8jBUhKN8JB8nmqvQo/nKdrBodBY7L3RhDSPPyvOHwLYNmPuhwuJq7a7C3vgFKWGQM+ecPStcvOHA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -12586,13 +13392,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "devOptional": true + "dev": true }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "devOptional": true, + "dev": true, "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -12641,13 +13447,12 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "devOptional": true }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -12657,7 +13462,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } @@ -12742,6 +13547,15 @@ } } }, + "node_modules/qlobber": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-5.0.3.tgz", + "integrity": "sha512-wW4GTZPePyh0RgOsM18oDyOUlXfurVRgoNyJfS+y7VWPyd0GYhQp5T2tycZFZjonH+hngxIfklGJhTP/ghidgQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/qrcode": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz", @@ -13267,6 +14081,11 @@ "jsesc": "bin/jsesc" } }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + }, "node_modules/remote-git-tags": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz", @@ -13276,6 +14095,84 @@ "node": ">=8" } }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "optional": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "optional": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "optional": true, + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -13375,11 +14272,17 @@ "lowercase-keys": "^1.0.0" } }, + "node_modules/retimer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==", + "dev": true + }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "devOptional": true, + "dev": true, "engines": { "node": ">= 4" } @@ -13394,6 +14297,11 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -13799,7 +14707,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "devOptional": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -13871,7 +14778,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "devOptional": true, "dependencies": { "ip": "^1.1.5", "smart-buffer": "^4.2.0" @@ -13885,7 +14791,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "devOptional": true, "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.1", @@ -13941,6 +14846,12 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, "node_modules/spawn-please": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-1.0.0.tgz", @@ -14002,17 +14913,50 @@ "specificity": "bin/specificity" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "optional": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "devOptional": true, + "dev": true, "dependencies": { "minipass": "^3.1.1" }, @@ -14049,6 +14993,11 @@ "node": ">= 0.6" } }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -14382,9 +15331,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", - "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -14650,6 +15599,24 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14695,6 +15662,11 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -14771,7 +15743,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "devOptional": true, + "dev": true, "dependencies": { "unique-slug": "^2.0.0" } @@ -14780,7 +15752,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "devOptional": true, + "dev": true, "dependencies": { "imurmurhash": "^0.1.4" } @@ -14946,7 +15918,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, + "devOptional": true, "dependencies": { "punycode": "^2.1.0" } @@ -14976,6 +15948,21 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uuid-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz", + "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==", + "dev": true + }, "node_modules/v-pagination-3": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/v-pagination-3/-/v-pagination-3-0.1.7.tgz", @@ -15026,12 +16013,15 @@ } }, "node_modules/validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", + "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", "dev": true, "dependencies": { - "builtins": "^1.0.3" + "builtins": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/vary": { @@ -15042,6 +16032,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + }, "node_modules/vite": { "version": "2.6.14", "resolved": "https://registry.npmjs.org/vite/-/vite-2.6.14.tgz", @@ -15245,6 +16255,17 @@ "npm": ">= 3.0.0" } }, + "node_modules/vue-prism-editor": { + "version": "2.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz", + "integrity": "sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/vue-qrcode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/vue-qrcode/-/vue-qrcode-1.0.0.tgz", @@ -15525,7 +16546,6 @@ "version": "7.5.7", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, "engines": { "node": ">=8.3.0" }, @@ -15568,7 +16588,15 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", "engines": { - "node": ">=0.4.0" + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" } }, "node_modules/y18n": { @@ -15667,15 +16695,15 @@ }, "dependencies": { "@actions/github": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", - "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.1.tgz", + "integrity": "sha512-JZGyPM9ektb8NVTTI/2gfJ9DL7Rk98tQ7OVyTlgTuaQroariRBsOnzjy0I2EarX4xUZpK88YyO503fhmjFdyAg==", "dev": true, "requires": { "@actions/http-client": "^1.0.11", - "@octokit/core": "^3.4.0", - "@octokit/plugin-paginate-rest": "^2.13.3", - "@octokit/plugin-rest-endpoint-methods": "^5.1.1" + "@octokit/core": "^3.6.0", + "@octokit/plugin-paginate-rest": "^2.17.0", + "@octokit/plugin-rest-endpoint-methods": "^5.13.0" } }, "@actions/http-client": { @@ -16902,7 +17930,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "devOptional": true + "dev": true }, "@hapi/hoek": { "version": "9.2.1", @@ -17520,24 +18548,25 @@ } }, "@louislam/sqlite3": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-6.0.1.tgz", - "integrity": "sha512-QGLj5bjQ+O4YSPj/qxtEAArbIqW9wNzBUamlIcRbvFjFiNokItwdubqL2Gl5iX0q1mUn3Z6NoFO1rrAZ/qqlsA==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@louislam/sqlite3/-/sqlite3-15.0.3.tgz", + "integrity": "sha512-rCH6PIaa+TgBzpTRnqBKUa4H/5G2hIk5ukYK5rXxK+8hVGykRin3UMGzGejrPzIKzDnZGByIF0XD4ndi6lprRQ==", "requires": { - "@mapbox/node-pre-gyp": "^1.0.7", - "node-addon-api": "^3.0.0", - "node-gyp": "^8.4.1" + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "node-gyp": "^7.1.2", + "tar": "^6.1.11" } }, "@mapbox/node-pre-gyp": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", - "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz", + "integrity": "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==", "requires": { - "detect-libc": "^1.0.3", + "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", + "node-fetch": "^2.6.7", "nopt": "^5.0.0", "npmlog": "^5.0.1", "rimraf": "^3.0.2", @@ -17581,27 +18610,6 @@ "fastq": "^1.6.0" } }, - "@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "devOptional": true, - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "devOptional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, "@npmcli/git": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.0.tgz", @@ -17620,9 +18628,9 @@ }, "dependencies": { "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true }, "semver": { @@ -17661,7 +18669,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "devOptional": true, + "dev": true, "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -17694,11 +18702,15 @@ "read-package-json-fast": "^2.0.3" }, "dependencies": { - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true + "@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } }, "are-we-there-yet": { "version": "3.0.0", @@ -17711,18 +18723,18 @@ } }, "cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "requires": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -17737,17 +18749,17 @@ }, "dependencies": { "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true } } }, "gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "dev": true, "requires": { "aproba": "^1.0.3 || ^2.0.0", @@ -17760,30 +18772,19 @@ "wide-align": "^1.1.5" } }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, "make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "requires": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -17796,17 +18797,17 @@ }, "dependencies": { "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true } } }, "minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -17967,9 +18968,9 @@ "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==" }, "@sideway/address": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz", - "integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", + "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", "dev": true, "requires": { "@hapi/hoek": "^9.0.0" @@ -18031,10 +19032,9 @@ } }, "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "devOptional": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, "@types/accepts": { "version": "1.3.5", @@ -18245,9 +19245,9 @@ } }, "@types/lodash": { - "version": "4.14.180", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.180.tgz", - "integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g==" + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==" }, "@types/mime": { "version": "1.3.2", @@ -18261,9 +19261,9 @@ "dev": true }, "@types/node": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.22.tgz", - "integrity": "sha512-8FwbVoG4fy+ykY86XCAclKZDORttqE5/s7dyWZKLXTdv3vRy5HozBEinG5IqhvPXXzIZEcTVbuHlQEI6iuwcmw==" + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -18427,9 +19427,9 @@ } }, "@vue/devtools-api": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.3.tgz", - "integrity": "sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==" + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.1.4.tgz", + "integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==" }, "@vue/reactivity": { "version": "3.2.31", @@ -18532,6 +19532,61 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "aedes": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/aedes/-/aedes-0.46.3.tgz", + "integrity": "sha512-i3B+H74uNRhlqcs/JdrMp7e3daz4Cwls0x4yLcfjGXz2tIwnxhF6od4m86O6yyNdz/Gg3jfY3q0sc/Cz8qzg6g==", + "dev": true, + "requires": { + "aedes-packet": "^2.3.1", + "aedes-persistence": "^8.1.3", + "bulk-write-stream": "^2.0.1", + "end-of-stream": "^1.4.4", + "fastfall": "^1.5.1", + "fastparallel": "^2.4.1", + "fastseries": "^2.0.0", + "hyperid": "^3.0.0", + "mqemitter": "^4.5.0", + "mqtt-packet": "^7.1.2", + "readable-stream": "^3.6.0", + "retimer": "^3.0.0", + "reusify": "^1.0.4", + "uuid": "^8.3.2" + }, + "dependencies": { + "mqtt-packet": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-7.1.2.tgz", + "integrity": "sha512-FFZbcZ2omsf4c5TxEQfcX9hI+JzDpDKPT46OmeIBpVA7+t32ey25UNqlqNXTmeZOr5BLsSIERpQQLsFWJS94SQ==", + "dev": true, + "requires": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + } + } + }, + "aedes-packet": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/aedes-packet/-/aedes-packet-2.3.1.tgz", + "integrity": "sha512-LqBd57uc2rui2RbjycW17dylglejG26mM4ewVXGNDnVp/SUHFVEgm7d1HTmYrnSkSCNoHti042qgcTwv/F+BtQ==", + "dev": true, + "requires": { + "mqtt-packet": "^6.3.0" + } + }, + "aedes-persistence": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/aedes-persistence/-/aedes-persistence-8.1.3.tgz", + "integrity": "sha512-VMCjEV+2g1TNJb/IlDEUy6SP9crT+QUhe2xc6UjyqrFNBNgTvHmOefXY7FxWrwmR2QA02vwg3+5p/JXkyg/Dkw==", + "dev": true, + "requires": { + "aedes-packet": "^2.3.1", + "from2": "^2.3.0", + "qlobber": "^5.0.3" + } + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -18544,7 +19599,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "devOptional": true, + "dev": true, "requires": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -18555,7 +19610,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "devOptional": true, + "dev": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -18565,7 +19620,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "devOptional": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -18672,6 +19727,21 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "optional": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "optional": true + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -18688,6 +19758,18 @@ "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.1.0.tgz", "integrity": "sha512-t7Zm5YGgEEc/3eYAicF32m/TNvL+XOeYZy9CvBUeJY/szM7frLolFylhrlZNWV/ohWhcUXygrBGjYmoQdxF4CQ==" }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "optional": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "optional": true + }, "axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -18902,8 +19984,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "base64id": { "version": "2.0.0", @@ -18925,6 +20006,15 @@ } } }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, "bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -18951,7 +20041,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -19155,7 +20244,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -19175,46 +20263,43 @@ "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.0.tgz", + "integrity": "sha512-aizhtbxgT1Udg0Fj6GssXshAVK+nxbtCV+1OtTrMNy67jffDFBY6CUBAkhO4owbleAx6fdbnWdpsmmcXydbzNw==", + "dev": true, + "requires": { + "semver": "^7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "bulk-write-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bulk-write-stream/-/bulk-write-stream-2.0.1.tgz", + "integrity": "sha512-XWOLjgHtpDasHfwM8oO4df1JoZwa7/OwTsXDzh4rUTo+9CowzeOFBZz43w+H14h1fyq+xl28tVIBrdjcjj4Gug==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "optional": true, - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -19280,11 +20365,17 @@ } }, "caniuse-lite": { - "version": "1.0.30001319", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz", - "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==", + "version": "1.0.30001323", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001323.tgz", + "integrity": "sha512-e4BF2RlCVELKx8+RmklSEIVub1TWrmdhvA5kEUueummz1XyySW0DVk+3x9HyhU9MuWTa2BhqLgEuEmUwASAdCA==", "dev": true }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "optional": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -19365,7 +20456,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "devOptional": true + "dev": true }, "cli-boxes": { "version": "2.2.1", @@ -19441,6 +20532,12 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true + }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -19512,6 +20609,22 @@ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true }, + "commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "requires": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + }, + "dependencies": { + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + } + } + }, "compare-versions": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", @@ -19527,6 +20640,110 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "concurrently": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.1.0.tgz", + "integrity": "sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -19610,6 +20827,12 @@ } } }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "devOptional": true + }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -19715,6 +20938,15 @@ "fs-exists-sync": "^0.1.0" } }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -19726,6 +20958,12 @@ "whatwg-url": "^8.0.0" } }, + "date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true + }, "dayjs": { "version": "1.10.8", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.8.tgz", @@ -19850,9 +21088,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==" }, "detect-newline": { "version": "3.1.0", @@ -19901,6 +21139,31 @@ "esutils": "^2.0.2" } }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, "domexception": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", @@ -19918,6 +21181,26 @@ } } }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -19933,6 +21216,27 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -19947,9 +21251,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.4.89", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.89.tgz", - "integrity": "sha512-z1Axg0Fu54fse8wN4fd+GAINdU5mJmLtcl6bqIcYyzNVGONcfHAeeJi88KYMQVKalhXlYuVPzKkFIU5VD0raUw==", + "version": "1.4.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", + "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", "dev": true }, "emittery": { @@ -19977,6 +21281,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "optional": true, "requires": { "iconv-lite": "^0.6.2" @@ -19986,7 +21291,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -20055,6 +21359,12 @@ "ansi-colors": "^4.1.1" } }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -20065,7 +21375,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "devOptional": true + "dev": true }, "error-ex": { "version": "1.3.2", @@ -20697,6 +22007,12 @@ "basic-auth": "^2.0.1" } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "optional": true + }, "extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -20720,11 +22036,17 @@ } } }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "optional": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "devOptional": true }, "fast-glob": { "version": "3.2.11", @@ -20743,7 +22065,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "devOptional": true }, "fast-levenshtein": { "version": "2.0.6", @@ -20763,6 +22085,25 @@ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", "dev": true }, + "fastfall": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/fastfall/-/fastfall-1.5.1.tgz", + "integrity": "sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q=", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "fastparallel": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/fastparallel/-/fastparallel-2.4.1.tgz", + "integrity": "sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4", + "xtend": "^4.0.2" + } + }, "fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -20772,6 +22113,12 @@ "reusify": "^1.0.4" } }, + "fastseries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fastseries/-/fastseries-2.0.0.tgz", + "integrity": "sha512-XBU9RXeoYc2/VnvMhplAxEmZLfIk7cvTBu+xwoBuTI8pL19E03cmca17QQycKIdxgwCeFA/a4u27gv1h3ya5LQ==", + "dev": true + }, "favico.js": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/favico.js/-/favico.js-0.3.10.tgz", @@ -20974,6 +22321,12 @@ "for-in": "^1.0.1" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "optional": true + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -21000,6 +22353,48 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -21104,6 +22499,15 @@ "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==" }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -21246,6 +22650,22 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "devOptional": true }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "optional": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "optional": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -21288,6 +22708,15 @@ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "dev": true }, + "help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "requires": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -21298,12 +22727,20 @@ } }, "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", + "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "lru-cache": "^7.5.1" + }, + "dependencies": { + "lru-cache": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", + "dev": true + } } }, "html-encoding-sniffer": { @@ -21327,11 +22764,23 @@ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true }, + "htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "devOptional": true + "dev": true }, "http-errors": { "version": "1.8.1", @@ -21354,16 +22803,26 @@ } }, "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "devOptional": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "requires": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -21391,11 +22850,21 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "devOptional": true, + "dev": true, "requires": { "ms": "^2.0.0" } }, + "hyperid": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hyperid/-/hyperid-3.0.1.tgz", + "integrity": "sha512-I+tl7TS5nsoVhkxqX1rS3Qmqlq44eoPUcgPthW8v3IW8CvWL7lwtd6HQbkDUMrBKJTG0vgEaRsjT35imW/D+9Q==", + "dev": true, + "requires": { + "uuid": "^8.3.2", + "uuid-parse": "^1.1.0" + } + }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -21407,8 +22876,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "4.0.6", @@ -21455,19 +22923,19 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "devOptional": true + "dev": true }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "devOptional": true + "dev": true }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "devOptional": true + "dev": true }, "inflight": { "version": "1.0.6", @@ -21497,8 +22965,7 @@ "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "devOptional": true + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" }, "ipaddr.js": { "version": "1.9.1", @@ -21620,7 +23087,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "devOptional": true + "dev": true }, "is-npm": { "version": "5.0.0", @@ -21693,7 +23160,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "devOptional": true }, "is-valid-path": { "version": "0.1.1", @@ -21715,6 +23182,12 @@ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "devOptional": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -21727,6 +23200,12 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "optional": true + }, "istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -23218,6 +24697,11 @@ "@sideway/pinpoint": "^2.0.0" } }, + "js-sdsl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-2.1.4.tgz", + "integrity": "sha512-/Ew+CJWHNddr7sjwgxaVeIORIH4AMVC9dy0hPf540ZGMVgS9d3ajwuVdyhDt6/QUvT8ATjR3yuYBKsS79F+H4A==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -23234,6 +24718,12 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -23269,6 +24759,12 @@ "xml-name-validator": "^3.0.0" }, "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -23285,6 +24781,17 @@ "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } } } }, @@ -23315,11 +24822,17 @@ "jju": "^1.1.0" } }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "optional": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "devOptional": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -23327,6 +24840,12 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "optional": true + }, "json5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", @@ -23369,6 +24888,18 @@ } } }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, "just-performance": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/just-performance/-/just-performance-4.3.0.tgz", @@ -23720,30 +25251,6 @@ "semver": "^6.0.0" } }, - "make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "optional": true, - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - } - }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -23790,6 +25297,15 @@ "yargs-parser": "^20.2.3" }, "dependencies": { + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -23858,13 +25374,13 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mime": { @@ -23914,8 +25430,7 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minimist-options": { "version": "4.1.0", @@ -23948,28 +25463,16 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } }, - "minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "optional": true, - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - } - }, "minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -23988,7 +25491,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -23997,7 +25500,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.0.0" } @@ -24040,6 +25543,50 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "mqemitter": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mqemitter/-/mqemitter-4.5.0.tgz", + "integrity": "sha512-Mp/zytFeIv6piJQkEKnncHcP4R/ErJc5C7dfonkhkNUT2LA/nTayrfNxbipp3M5iCJUTQSUtzfQAQA3XVcKz6w==", + "dev": true, + "requires": { + "fastparallel": "^2.3.0", + "qlobber": "^5.0.0" + } + }, + "mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "requires": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + } + }, + "mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "requires": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -24051,9 +25598,9 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", + "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==" }, "natural-compare": { "version": "1.4.0", @@ -24067,9 +25614,17 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, + "node-cloudflared-tunnel": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/node-cloudflared-tunnel/-/node-cloudflared-tunnel-1.0.9.tgz", + "integrity": "sha512-d0mhIM5P2ldE2yHChehC6EvnpFCkifWRzWrW81gVWdcCWqNcyISXuDdOYzRW5mwmjWuT6WNtLJoGQ84uqS4EmA==", + "requires": { + "command-exists": "^1.2.9" + } }, "node-fetch": { "version": "2.6.7", @@ -24101,69 +25656,140 @@ } }, "node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "optional": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", + "graceful-fs": "^4.2.3", "nopt": "^5.0.0", - "npmlog": "^6.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", + "semver": "^7.3.2", + "tar": "^6.0.2", "which": "^2.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, "are-we-there-yet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", - "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "number-is-nan": "^1.0.0" } }, - "gauge": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.3.tgz", - "integrity": "sha512-ICw1DhAwMtb22rYFwEHgJcx1JCwJGv3x6G0OQUq56Nge+H4Q8JEwr8iveS0XFlsUNSI67F5ffMGK25bK4Pmskw==", + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "optional": true, "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, - "npmlog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", - "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "optional": true, "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "optional": true, "requires": { "lru-cache": "^6.0.0" } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } } } }, @@ -24204,23 +25830,6 @@ "validate-npm-package-license": "^3.0.4" }, "dependencies": { - "hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - }, - "dependencies": { - "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true - } - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -24265,9 +25874,9 @@ } }, "npm-check-updates": { - "version": "12.5.4", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.4.tgz", - "integrity": "sha512-4+27zaTdieWgvPLaCZ/A6Q2WC1cYVcrc2SqVmLFYgkWBrKw1QkwpeV16FSvkFGZr3OdFyr7Dpjw8JRn4H2QxFw==", + "version": "12.5.5", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-12.5.5.tgz", + "integrity": "sha512-7LH6KN6F1fZMtY4zNYAQPpJU1ToxZ6sSCxk948vrLIz97aNqmPLSX72MrmbOWwpyBgLCPbFJWY/k3zE18pmxfw==", "dev": true, "requires": { "chalk": "^4.1.2", @@ -24279,7 +25888,7 @@ "fp-and-or": "^0.1.3", "get-stdin": "^8.0.0", "globby": "^11.0.4", - "hosted-git-info": "^4.1.0", + "hosted-git-info": "^5.0.0", "json-parse-helpfulerror": "^1.0.3", "jsonlines": "^0.1.1", "libnpmconfig": "^1.2.1", @@ -24449,33 +26058,16 @@ "dev": true }, "npm-package-arg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.1.tgz", - "integrity": "sha512-Xs9wznfEAmZAR61qsYH3iN24V/qMYYkvAR5CRQNMvC6PjN2fHtO8y9XP/xdp5K+Icx+u1wMBMgWRPCmAEChSog==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.0.2.tgz", + "integrity": "sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^3.0.0" + "validate-npm-package-name": "^4.0.0" }, "dependencies": { - "hosted-git-info": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-5.0.0.tgz", - "integrity": "sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q==", - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - }, - "dependencies": { - "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", - "dev": true - } - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -24523,39 +26115,43 @@ } }, "npm-registry-fetch": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.0.1.tgz", - "integrity": "sha512-Ak+LXVtSrCLOdscFW/apUw67OPNph8waHsPKM9UOJosL7i59EF5XoSWQMEsXEOeifM9Bb4/2+WrQC4t/pd8DGg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.1.0.tgz", + "integrity": "sha512-TIYL5X8CcwDhbFMXFDShNcpG6OMCYK6VzvSr6MUWP20tCU2DJ4ao2qQg3DT+3Pet8mO6/cgbZpon4LMh3duYLg==", "dev": true, "requires": { - "make-fetch-happen": "^10.0.3", + "make-fetch-happen": "^10.0.6", "minipass": "^3.1.6", - "minipass-fetch": "^2.0.1", + "minipass-fetch": "^2.0.3", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.0", + "npm-package-arg": "^9.0.1", "proc-log": "^2.0.0" }, "dependencies": { - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true + "@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } }, "cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "requires": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -24569,36 +26165,25 @@ "unique-filename": "^1.1.1" } }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true }, "make-fetch-happen": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.6.tgz", - "integrity": "sha512-4Gfh6lV3TLXmj7qz79hBFuvVqjYSMW6v2+sxtdX4LFQU0rK3V/txRjE0DoZb7X0IF3t9f8NO3CxPSWlvdckhVA==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.1.1.tgz", + "integrity": "sha512-3/mCljDQNjmrP7kl0vhS5WVlV+TvSKoZaFhdiYV7MOijEnrhrjaVnqbp/EY/7S+fhUB2KpH7j8c1iRsIOs+kjw==", "dev": true, "requires": { "agentkeepalive": "^4.2.1", - "cacache": "^16.0.0", + "cacache": "^16.0.2", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", @@ -24611,9 +26196,9 @@ } }, "minipass-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.0.3.tgz", - "integrity": "sha512-VA+eiiUtaIvpQJXISwE3OiMvQwAWrgKb97F0aXlCS1Ahikr8fEQq8m3Hf7Kv9KT3nokuHigJKsDMB6atU04olQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.0.tgz", + "integrity": "sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -24621,6 +26206,26 @@ "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } } } }, @@ -24644,6 +26249,21 @@ "set-blocking": "^2.0.0" } }, + "number-allocator": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.10.tgz", + "integrity": "sha512-K4AvNGKo9lP6HqsZyfSr9KDaqnwFzW203inhQEOwFrmFaYevpdX4VNwdOLk197aHujzbT//z6pCBrCOUYSM5iw==", + "requires": { + "debug": "^4.3.1", + "js-sdsl": "^2.1.2" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true + }, "numbered": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/numbered/-/numbered-1.1.0.tgz", @@ -24655,6 +26275,12 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "optional": true + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -24754,7 +26380,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "devOptional": true, + "dev": true, "requires": { "aggregate-error": "^3.0.0" } @@ -24821,19 +26447,29 @@ "tar": "^6.1.11" }, "dependencies": { + "@npmcli/fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.0.tgz", + "integrity": "sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } + }, "cacache": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.2.tgz", - "integrity": "sha512-Q17j7s8X81i/QYVrKVQ/qwWGT+pYLfpTcZ+X+p/Qw9FULy9JEfb2FECYTTt6mPV6A/vk92nRZ80ncpKxiGTrIA==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.0.3.tgz", + "integrity": "sha512-eC7wYodNCVb97kuHGk5P+xZsvUJHkhSEOyNwkenqQPAsOtrTjvWOE5vSPNBpz9d8X3acIf6w2Ub5s4rvOCTs4g==", "dev": true, "requires": { - "@npmcli/fs": "^1.0.0", + "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^1.1.2", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^7.2.0", "infer-owner": "^1.0.4", - "lru-cache": "^7.5.1", + "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", @@ -24848,10 +26484,30 @@ } }, "lru-cache": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.1.tgz", - "integrity": "sha512-cRffBiTW8s73eH4aTXqBcTLU0xQnwGV3/imttRHGWCrbergmnK4D6JXQd8qin5z43HnDwRI+o7mVW0LEB+tpAw==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.7.3.tgz", + "integrity": "sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==", "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } + } } } }, @@ -24952,6 +26608,12 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "optional": true + }, "pg-connection-string": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", @@ -25003,6 +26665,17 @@ "source-map-js": "^1.0.2" } }, + "postcss-html": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.3.1.tgz", + "integrity": "sha512-SJ7iRw+IngyZv3Z9lChlZU30a9y9MZjZZcoUJmx0T/nKE9S+hetJ8fAv/MRu4bPnGDsXhVlaFs5+umpK3yaaQQ==", + "dev": true, + "requires": { + "htmlparser2": "^7.1.2", + "postcss": "^8.4.0", + "postcss-safe-parser": "^6.0.0" + } + }, "postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -25035,9 +26708,9 @@ "integrity": "sha512-j4KxzWovfdHsyxwl1BxkUal/O4uirvHgdzMKS1aWJBAV0qh2qj5qAZqpeBfVUYGWv+4iK9Az7SPyZ4fyNju1uA==" }, "postcss-selector-parser": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz", - "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -25081,12 +26754,22 @@ } } }, + "prismjs": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==" + }, "proc-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.0.tgz", - "integrity": "sha512-I/35MfCX2H8jBUhKN8JB8nmqvQo/nKdrBodBY7L3RhDSPPyvOHwLYNmPuhwuJq7a7C3vgFKWGQM+ecPStcvOHA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", + "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", "dev": true }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -25128,13 +26811,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "devOptional": true + "dev": true }, "promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "devOptional": true, + "dev": true, "requires": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -25174,13 +26857,12 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "devOptional": true }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -25190,7 +26872,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "devOptional": true }, "pupa": { "version": "2.1.1", @@ -25244,6 +26926,12 @@ } } }, + "qlobber": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-5.0.3.tgz", + "integrity": "sha512-wW4GTZPePyh0RgOsM18oDyOUlXfurVRgoNyJfS+y7VWPyd0GYhQp5T2tycZFZjonH+hngxIfklGJhTP/ghidgQ==", + "dev": true + }, "qrcode": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz", @@ -25660,12 +27348,80 @@ } } }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + }, "remote-git-tags": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz", "integrity": "sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==", "dev": true }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "optional": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "optional": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "optional": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "optional": true + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -25740,11 +27496,17 @@ "lowercase-keys": "^1.0.0" } }, + "retimer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/retimer/-/retimer-3.0.0.tgz", + "integrity": "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==", + "dev": true + }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "devOptional": true + "dev": true }, "reusify": { "version": "1.0.4", @@ -25752,6 +27514,11 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -26045,8 +27812,7 @@ "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "devOptional": true + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" }, "socket.io": { "version": "4.4.1", @@ -26104,7 +27870,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "devOptional": true, "requires": { "ip": "^1.1.5", "smart-buffer": "^4.2.0" @@ -26114,7 +27879,6 @@ "version": "6.1.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "devOptional": true, "requires": { "agent-base": "^6.0.2", "debug": "^4.3.1", @@ -26160,6 +27924,12 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, "spawn-please": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-1.0.0.tgz", @@ -26215,17 +27985,42 @@ "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", "dev": true }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "devOptional": true, + "dev": true, "requires": { "minipass": "^3.1.1" } @@ -26252,6 +28047,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -26510,9 +28310,9 @@ }, "dependencies": { "ajv": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", - "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -26727,6 +28527,21 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -26757,6 +28572,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -26814,7 +28634,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "devOptional": true, + "dev": true, "requires": { "unique-slug": "^2.0.0" } @@ -26823,7 +28643,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "devOptional": true, + "dev": true, "requires": { "imurmurhash": "^0.1.4" } @@ -26946,7 +28766,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, + "devOptional": true, "requires": { "punycode": "^2.1.0" } @@ -26970,6 +28790,18 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "uuid-parse": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/uuid-parse/-/uuid-parse-1.1.0.tgz", + "integrity": "sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==", + "dev": true + }, "v-pagination-3": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/v-pagination-3/-/v-pagination-3-0.1.7.tgz", @@ -27016,12 +28848,12 @@ } }, "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", + "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", "dev": true, "requires": { - "builtins": "^1.0.3" + "builtins": "^5.0.0" } }, "vary": { @@ -27029,6 +28861,25 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + } + } + }, "vite": { "version": "2.6.14", "resolved": "https://registry.npmjs.org/vite/-/vite-2.6.14.tgz", @@ -27151,6 +29002,11 @@ "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-3.0.0-alpha.2.tgz", "integrity": "sha512-Xp9fGJECns45v+v8jXbCIsAkCybYkEg0lNwr7Z6HDUSMyx2TEIK2giipPE+qXiShEc1Ipn+ZtttH2iq9hwXP4Q==" }, + "vue-prism-editor": { + "version": "2.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/vue-prism-editor/-/vue-prism-editor-2.0.0-alpha.2.tgz", + "integrity": "sha512-Gu42ba9nosrE+gJpnAEuEkDMqG9zSUysIR8SdXUw8MQKDjBnnNR9lHC18uOr/ICz7yrA/5c7jHJr9lpElODC7w==" + }, "vue-qrcode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/vue-qrcode/-/vue-qrcode-1.0.0.tgz", @@ -27369,8 +29225,7 @@ "ws": { "version": "7.5.7", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==" }, "xdg-basedir": { "version": "4.0.0", @@ -27395,6 +29250,11 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 326ebf1432..8a8bd1ebd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uptime-kuma", - "version": "1.13.1", + "version": "1.15.0", "license": "MIT", "repository": { "type": "git", @@ -13,14 +13,16 @@ "install-legacy": "npm install --legacy-peer-deps", "update-legacy": "npm update --legacy-peer-deps", "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", + "lint-fix:js": "eslint --ext \".js,.vue\" --fix --ignore-path .gitignore .", "lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore", "lint": "npm run lint:js && npm run lint:style", - "dev": "vite --host --config ./config/vite.config.js", + "dev": "concurrently -k -r \"wait-on tcp:3000 && npm run start-server-dev \" \"npm run start-frontend-dev\"", + "start-frontend-dev": "cross-env NODE_ENV=development vite --host --config ./config/vite.config.js", "start": "npm run start-server", "start-server": "node server/server.js", "start-server-dev": "cross-env NODE_ENV=development node server/server.js", "build": "vite build --config ./config/vite.config.js", - "test": "node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --test", + "test": "npm run lint && node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --test", "test-with-build": "npm run build && npm test", "jest": "node test/prepare-jest.js && npm run jest-frontend && npm run jest-backend", "jest-frontend": "cross-env TEST_FRONTEND=1 jest --config=./config/jest-frontend.config.js", @@ -36,7 +38,7 @@ "build-docker-nightly-alpine": "docker buildx build -f docker/dockerfile-alpine --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:nightly-alpine --target nightly . --push", "build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain", "upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain", - "setup": "git checkout 1.13.1 && npm ci --production && npm run download-dist", + "setup": "git checkout 1.15.0 && npm ci --production && npm run download-dist", "download-dist": "node extra/download-dist.js", "mark-as-nightly": "node extra/mark-as-nightly.js", "reset-password": "node extra/reset-password.js", @@ -48,10 +50,11 @@ "test-install-script-ubuntu1604": "npm run compile-install-script && docker build --progress plain -f test/test_install_script/ubuntu1604.dockerfile .", "test-nodejs16": "docker build --progress plain -f test/ubuntu-nodejs16.dockerfile .", "simple-dns-server": "node extra/simple-dns-server.js", + "simple-mqtt-server": "node extra/simple-mqtt-server.js", "update-language-files-with-base-lang": "cd extra/update-language-files && node index.js %npm_config_base_lang% && eslint ../../src/languages/**.js --fix", "update-language-files": "cd extra/update-language-files && node index.js && eslint ../../src/languages/**.js --fix", "ncu-patch": "npm-check-updates -u -t patch", - "release-final": "node extra/update-version.js && npm run build-docker && git push --tags && node ./extra/press-any-key.js && npm run upload-artifacts && node ./extra/update-wiki-version.js", + "release-final": "node extra/update-version.js && npm run build-docker && node ./extra/press-any-key.js && npm run upload-artifacts && node ./extra/update-wiki-version.js", "release-beta": "node extra/beta/update-version.js && npm run build && node ./extra/env2arg.js docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:$VERSION -t louislam/uptime-kuma:beta . --target release --push && node ./extra/press-any-key.js && npm run upload-artifacts", "git-remove-tag": "git tag -d" }, @@ -60,7 +63,7 @@ "@fortawesome/free-regular-svg-icons": "~5.15.4", "@fortawesome/free-solid-svg-icons": "~5.15.4", "@fortawesome/vue-fontawesome": "~3.0.0-5", - "@louislam/sqlite3": "~6.0.1", + "@louislam/sqlite3": "~15.0.3", "@popperjs/core": "~2.10.2", "args-parser": "~1.3.0", "axios": "~0.26.1", @@ -79,21 +82,27 @@ "favico.js": "^0.3.10", "form-data": "~4.0.0", "http-graceful-shutdown": "~3.1.7", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", "iconv-lite": "^0.6.3", "jsonwebtoken": "~8.5.1", "jwt-decode": "^3.1.2", "limiter": "^2.1.0", + "mqtt": "^4.2.8", + "node-cloudflared-tunnel": "~1.0.9", "nodemailer": "~6.6.5", "notp": "~2.0.3", "password-hash": "~1.2.2", "postcss-rtlcss": "~3.4.1", "postcss-scss": "~4.0.3", + "prismjs": "^1.27.0", "prom-client": "~13.2.0", "prometheus-api-metrics": "~3.2.1", "qrcode": "~1.5.0", "redbean-node": "0.1.3", "socket.io": "~4.4.1", "socket.io-client": "~4.4.1", + "socks-proxy-agent": "^6.1.1", "tar": "^6.1.11", "tcp-ping": "~0.1.1", "thirty-two": "~1.0.2", @@ -106,20 +115,23 @@ "vue-i18n": "~9.1.9", "vue-image-crop-upload": "~3.0.3", "vue-multiselect": "~3.0.0-alpha.2", + "vue-prism-editor": "^2.0.0-alpha.2", "vue-qrcode": "~1.0.0", "vue-router": "~4.0.14", "vue-toastification": "~2.0.0-rc.5", "vuedraggable": "~4.1.0" }, "devDependencies": { - "@actions/github": "~5.0.0", + "@actions/github": "~5.0.1", "@babel/eslint-parser": "~7.15.8", "@babel/preset-env": "^7.15.8", "@types/bootstrap": "~5.1.9", "@vitejs/plugin-legacy": "~1.6.4", "@vitejs/plugin-vue": "~1.9.4", "@vue/compiler-sfc": "~3.2.31", + "aedes": "^0.46.3", "babel-plugin-rewire": "~1.2.0", + "concurrently": "^7.1.0", "core-js": "~3.18.3", "cross-env": "~7.0.3", "dns2": "~2.0.1", @@ -127,12 +139,14 @@ "eslint-plugin-vue": "~7.18.0", "jest": "~27.2.5", "jest-puppeteer": "~6.0.3", - "npm-check-updates": "^12.5.4", + "npm-check-updates": "^12.5.5", + "postcss-html": "^1.3.1", "puppeteer": "~13.1.3", "sass": "~1.42.1", "stylelint": "~14.2.0", "stylelint-config-standard": "~24.0.0", "typescript": "~4.4.4", - "vite": "~2.6.14" + "vite": "~2.6.14", + "wait-on": "^6.0.1" } } diff --git a/server/2fa.js b/server/2fa.js index bc8145cffe..f8d700bf0d 100644 --- a/server/2fa.js +++ b/server/2fa.js @@ -1,4 +1,3 @@ -const { checkLogin } = require("./util-server"); const { R } = require("redbean-node"); class TwoFA { diff --git a/server/auth.js b/server/auth.js index 1196f94d79..d9412ae37a 100644 --- a/server/auth.js +++ b/server/auth.js @@ -2,7 +2,6 @@ const basicAuth = require("express-basic-auth"); const passwordHash = require("./password-hash"); const { R } = require("redbean-node"); const { setting } = require("./util-server"); -const { debug } = require("../src/util"); const { loginRateLimiter } = require("./rate-limiter"); /** @@ -12,6 +11,10 @@ const { loginRateLimiter } = require("./rate-limiter"); * @returns {Promise} */ exports.login = async function (username, password) { + if (typeof username !== "string" || typeof password !== "string") { + return null; + } + let user = await R.findOne("user", " username = ? AND active = 1 ", [ username, ]); @@ -30,6 +33,13 @@ exports.login = async function (username, password) { return null; }; +/** + * A function that checks if a user is logged in. + * @param {string} username The username of the user to check for. + * @param {function} callback The callback to call when done, with an error and result parameter. + * + * Generated by Trelent + */ function myAuthorizer(username, password, callback) { // Login Rate Limit loginRateLimiter.pass(null, 0).then((pass) => { diff --git a/server/check-version.js b/server/check-version.js index f3b15e8487..c9d87c96f1 100644 --- a/server/check-version.js +++ b/server/check-version.js @@ -17,7 +17,7 @@ exports.startInterval = () => { res.data.slow = "1000.0.0"; } - if (!await setting("checkUpdate")) { + if (await setting("checkUpdate") === false) { return; } diff --git a/server/client.js b/server/client.js index c7b3bc1629..ee925b3571 100644 --- a/server/client.js +++ b/server/client.js @@ -3,10 +3,17 @@ */ const { TimeLogger } = require("../src/util"); const { R } = require("redbean-node"); -const { io } = require("./server"); +const { UptimeKumaServer } = require("./uptime-kuma-server"); +const io = UptimeKumaServer.getInstance().io; const { setting } = require("./util-server"); const checkVersion = require("./check-version"); +/** + * Send a list of notifications to the user. + * @param {Socket} socket The socket object that is connected to the client. + * + * Generated by Trelent + */ async function sendNotificationList(socket) { const timeLogger = new TimeLogger(); @@ -83,6 +90,29 @@ async function sendImportantHeartbeatList(socket, monitorID, toUser = false, ove } +/** + * Delivers proxy list + * + * @param socket + * @return {Promise} + */ +async function sendProxyList(socket) { + const timeLogger = new TimeLogger(); + + const list = await R.find("proxy", " user_id = ? ", [ socket.userID ]); + io.to(socket.userID).emit("proxyList", list.map(bean => bean.export())); + + timeLogger.print("Send Proxy List"); + + return list; +} + +/** + * Emits the version information to the client. + * @param {Socket} socket The socket object that is connected to the client. + * + * Generated by Trelent + */ async function sendInfo(socket) { socket.emit("info", { version: checkVersion.version, @@ -95,6 +125,6 @@ module.exports = { sendNotificationList, sendImportantHeartbeatList, sendHeartbeatList, - sendInfo + sendProxyList, + sendInfo, }; - diff --git a/server/database.js b/server/database.js index 5cd57c9d8f..099d15d562 100644 --- a/server/database.js +++ b/server/database.js @@ -1,7 +1,7 @@ const fs = require("fs"); const { R } = require("redbean-node"); const { setSetting, setting } = require("./util-server"); -const { debug, sleep } = require("../src/util"); +const { log, sleep } = require("../src/util"); const dayjs = require("dayjs"); const knex = require("knex"); @@ -54,6 +54,10 @@ class Database { "patch-notification_sent_history.sql": true, "patch-monitor-basic-auth.sql": true, "patch-status-page.sql": true, + "patch-proxy.sql": true, + "patch-monitor-expiry-notification.sql": true, + "patch-status-page-footer-css.sql": true, + "patch-added-mqtt-monitor.sql": true, } /** @@ -78,10 +82,10 @@ class Database { fs.mkdirSync(Database.uploadDir, { recursive: true }); } - console.log(`Data Dir: ${Database.dataDir}`); + log.info("db", `Data Dir: ${Database.dataDir}`); } - static async connect(testMode = false) { + static async connect(testMode = false, autoloadModels = true, noLog = false) { const acquireConnectionTimeout = 120 * 1000; const Dialect = require("knex/lib/dialects/sqlite3/index.js"); @@ -111,7 +115,10 @@ class Database { // Auto map the model to a bean object R.freeze(true); - await R.autoloadModels("./server/model"); + + if (autoloadModels) { + await R.autoloadModels("./server/model"); + } await R.exec("PRAGMA foreign_keys = ON"); if (testMode) { @@ -124,10 +131,17 @@ class Database { await R.exec("PRAGMA cache_size = -12000"); await R.exec("PRAGMA auto_vacuum = FULL"); - console.log("SQLite config:"); - console.log(await R.getAll("PRAGMA journal_mode")); - console.log(await R.getAll("PRAGMA cache_size")); - console.log("SQLite Version: " + await R.getCell("SELECT sqlite_version()")); + // This ensures that an operating system crash or power failure will not corrupt the database. + // FULL synchronous is very safe, but it is also slower. + // Read more: https://sqlite.org/pragma.html#pragma_synchronous + await R.exec("PRAGMA synchronous = FULL"); + + if (!noLog) { + log.info("db", "SQLite config:"); + log.info("db", await R.getAll("PRAGMA journal_mode")); + log.info("db", await R.getAll("PRAGMA cache_size")); + log.info("db", "SQLite Version: " + await R.getCell("SELECT sqlite_version()")); + } } static async patch() { @@ -137,15 +151,15 @@ class Database { version = 0; } - console.info("Your database version: " + version); - console.info("Latest database version: " + this.latestVersion); + log.info("db", "Your database version: " + version); + log.info("db", "Latest database version: " + this.latestVersion); if (version === this.latestVersion) { - console.info("Database patch not needed"); + log.info("db", "Database patch not needed"); } else if (version > this.latestVersion) { - console.info("Warning: Database version is newer than expected"); + log.info("db", "Warning: Database version is newer than expected"); } else { - console.info("Database patch is needed"); + log.info("db", "Database patch is needed"); this.backup(version); @@ -153,17 +167,17 @@ class Database { try { for (let i = version + 1; i <= this.latestVersion; i++) { const sqlFile = `./db/patch${i}.sql`; - console.info(`Patching ${sqlFile}`); + log.info("db", `Patching ${sqlFile}`); await Database.importSQLFile(sqlFile); - console.info(`Patched ${sqlFile}`); + log.info("db", `Patched ${sqlFile}`); await setSetting("database_version", i); } } catch (ex) { await Database.close(); - console.error(ex); - console.error("Start Uptime-Kuma failed due to issue patching the database"); - console.error("Please submit a bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); + log.error("db", ex); + log.error("db", "Start Uptime-Kuma failed due to issue patching the database"); + log.error("db", "Please submit a bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); this.restore(); process.exit(1); @@ -179,15 +193,15 @@ class Database { * @returns {Promise} */ static async patch2() { - console.log("Database Patch 2.0 Process"); + log.info("db", "Database Patch 2.0 Process"); let databasePatchedFiles = await setting("databasePatchedFiles"); if (! databasePatchedFiles) { databasePatchedFiles = {}; } - debug("Patched files:"); - debug(databasePatchedFiles); + log.debug("db", "Patched files:"); + log.debug("db", databasePatchedFiles); try { for (let sqlFilename in this.patchList) { @@ -195,15 +209,15 @@ class Database { } if (this.patched) { - console.log("Database Patched Successfully"); + log.info("db", "Database Patched Successfully"); } } catch (ex) { await Database.close(); - console.error(ex); - console.error("Start Uptime-Kuma failed due to issue patching the database"); - console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); + log.error("db", ex); + log.error("db", "Start Uptime-Kuma failed due to issue patching the database"); + log.error("db", "Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues"); this.restore(); @@ -290,16 +304,16 @@ class Database { let value = this.patchList[sqlFilename]; if (! value) { - console.log(sqlFilename + " skip"); + log.info("db", sqlFilename + " skip"); return; } // Check if patched if (! databasePatchedFiles[sqlFilename]) { - console.log(sqlFilename + " is not patched"); + log.info("db", sqlFilename + " is not patched"); if (value.parents) { - console.log(sqlFilename + " need parents"); + log.info("db", sqlFilename + " need parents"); for (let parentSQLFilename of value.parents) { await this.patch2Recursion(parentSQLFilename, databasePatchedFiles); } @@ -307,14 +321,14 @@ class Database { this.backup(dayjs().format("YYYYMMDDHHmmss")); - console.log(sqlFilename + " is patching"); + log.info("db", sqlFilename + " is patching"); this.patched = true; await this.importSQLFile("./db/" + sqlFilename); databasePatchedFiles[sqlFilename] = true; - console.log(sqlFilename + " was patched successfully"); + log.info("db", sqlFilename + " was patched successfully"); } else { - debug(sqlFilename + " is already patched, skip"); + log.debug("db", sqlFilename + " is already patched, skip"); } } @@ -366,7 +380,7 @@ class Database { }; process.addListener("unhandledRejection", listener); - console.log("Closing the database"); + log.info("db", "Closing the database"); while (true) { Database.noReject = true; @@ -376,10 +390,10 @@ class Database { if (Database.noReject) { break; } else { - console.log("Waiting to close the database"); + log.info("db", "Waiting to close the database"); } } - console.log("SQLite closed"); + log.info("db", "SQLite closed"); process.removeListener("unhandledRejection", listener); } @@ -391,7 +405,7 @@ class Database { */ static backup(version) { if (! this.backupPath) { - console.info("Backing up the database"); + log.info("db", "Backing up the database"); this.backupPath = this.dataDir + "kuma.db.bak" + version; fs.copyFileSync(Database.path, this.backupPath); @@ -414,7 +428,7 @@ class Database { */ static restore() { if (this.backupPath) { - console.error("Patching the database failed!!! Restoring the backup"); + log.error("db", "Patching the database failed!!! Restoring the backup"); const shmPath = Database.path + "-shm"; const walPath = Database.path + "-wal"; @@ -433,7 +447,7 @@ class Database { fs.unlinkSync(walPath); } } catch (e) { - console.log("Restore failed; you may need to restore the backup manually"); + log.error("db", "Restore failed; you may need to restore the backup manually"); process.exit(1); } @@ -449,14 +463,14 @@ class Database { } } else { - console.log("Nothing to restore"); + log.info("db", "Nothing to restore"); } } static getSize() { - debug("Database.getSize()"); + log.debug("db", "Database.getSize()"); let stats = fs.statSync(Database.path); - debug(stats); + log.debug("db", stats); return stats.size; } diff --git a/server/image-data-uri.js b/server/image-data-uri.js index 3ccaab7d5c..fbff934085 100644 --- a/server/image-data-uri.js +++ b/server/image-data-uri.js @@ -3,12 +3,19 @@ Modified with 0 dependencies */ let fs = require("fs"); +const { log } = require("../src/util"); let ImageDataURI = (() => { + /** + * @param {string} dataURI - A string that is a valid Data URI. + * @returns {?Object} An object with properties "imageType" and "dataBase64". The former is the image type, e.g., "png", and the latter is a base64 encoded string of the image's binary data. If it fails to parse, returns null instead of an object. + * + * Generated by Trelent + */ function decode(dataURI) { if (!/data:image\//.test(dataURI)) { - console.log("ImageDataURI :: Error :: It seems that it is not an Image Data URI. Couldn't match \"data:image/\""); + log.error("image-data-uri", "It seems that it is not an Image Data URI. Couldn't match \"data:image/\""); return null; } @@ -20,9 +27,16 @@ let ImageDataURI = (() => { }; } + /** + * @param {Buffer} data - The image data to be encoded. + * @param {String} mediaType - The type of the image, e.g., "image/png". + * @returns {String|null} A string representing the base64-encoded version of the given Buffer object or null if an error occurred. + * + * Generated by Trelent + */ function encode(data, mediaType) { if (!data || !mediaType) { - console.log("ImageDataURI :: Error :: Missing some of the required params: data, mediaType "); + log.error("image-data-uri", "Missing some of the required params: data, mediaType"); return null; } @@ -33,6 +47,13 @@ let ImageDataURI = (() => { return dataImgBase64; } + /** + * Converts a data URI to a file path. + * @param {string} dataURI The Data URI of the image. + * @param {string} [filePath] The path where the image will be saved, defaults to "./". + * + * Generated by Trelent + */ function outputFile(dataURI, filePath) { filePath = filePath || "./"; return new Promise((resolve, reject) => { diff --git a/server/jobs.js b/server/jobs.js index 0469d5cab6..739e867d4a 100644 --- a/server/jobs.js +++ b/server/jobs.js @@ -1,7 +1,8 @@ const path = require("path"); const Bree = require("bree"); const { SHARE_ENV } = require("worker_threads"); - +const { log } = require("../src/util"); +let bree; const jobs = [ { name: "clear-old-data", @@ -10,7 +11,7 @@ const jobs = [ ]; const initBackgroundJobs = function (args) { - const bree = new Bree({ + bree = new Bree({ root: path.resolve("server", "jobs"), jobs, worker: { @@ -18,7 +19,7 @@ const initBackgroundJobs = function (args) { workerData: args, }, workerMessageHandler: (message) => { - console.log("[Background Job]:", message); + log.info("jobs", message); } }); @@ -26,6 +27,13 @@ const initBackgroundJobs = function (args) { return bree; }; +const stopBackgroundJobs = function () { + if (bree) { + bree.stop(); + } +}; + module.exports = { - initBackgroundJobs + initBackgroundJobs, + stopBackgroundJobs }; diff --git a/server/jobs/clear-old-data.js b/server/jobs/clear-old-data.js index 7c368014d8..0ec5ffa5f1 100644 --- a/server/jobs/clear-old-data.js +++ b/server/jobs/clear-old-data.js @@ -30,7 +30,7 @@ const DEFAULT_KEEP_PERIOD = 180; try { await R.exec( "DELETE FROM heartbeat WHERE time < DATETIME('now', '-' || ? || ' days') ", - [parsedPeriod] + [ parsedPeriod ] ); } catch (e) { log(`Failed to clear old data: ${e.message}`); diff --git a/server/jobs/util-worker.js b/server/jobs/util-worker.js index 9426840d77..f122e6821a 100644 --- a/server/jobs/util-worker.js +++ b/server/jobs/util-worker.js @@ -9,7 +9,7 @@ const log = function (any) { }; const exit = function (error) { - if (error && error != 0) { + if (error && error !== 0) { process.exit(error); } else { if (parentPort) { diff --git a/server/model/monitor.js b/server/model/monitor.js index bafc0d2dd4..2abf4be3be 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -6,11 +6,12 @@ dayjs.extend(utc); dayjs.extend(timezone); const axios = require("axios"); const { Prometheus } = require("../prometheus"); -const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util"); -const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, errorLog } = require("../util-server"); +const { log, UP, DOWN, PENDING, flipStatus, TimeLogger } = require("../../src/util"); +const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, errorLog, mqttAsync } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); const { Notification } = require("../notification"); +const { Proxy } = require("../proxy"); const { demoMode } = require("../config"); const version = require("../../package.json").version; const apicache = require("../modules/apicache"); @@ -41,7 +42,7 @@ class Monitor extends BeanModel { /** * Return an object that ready to parse to JSON */ - async toJSON() { + async toJSON(includeSensitiveData = true) { let notificationIDList = {}; @@ -55,15 +56,11 @@ class Monitor extends BeanModel { const tags = await this.getTags(); - return { + let data = { id: this.id, name: this.name, url: this.url, method: this.method, - body: this.body, - headers: this.headers, - basic_auth_user: this.basic_auth_user, - basic_auth_pass: this.basic_auth_pass, hostname: this.hostname, port: this.port, maxretries: this.maxretries, @@ -73,6 +70,7 @@ class Monitor extends BeanModel { interval: this.interval, retryInterval: this.retryInterval, keyword: this.keyword, + expiryNotification: this.isEnabledExpiryNotification(), ignoreTls: this.getIgnoreTls(), upsideDown: this.isUpsideDown(), maxredirects: this.maxredirects, @@ -80,14 +78,31 @@ class Monitor extends BeanModel { dns_resolve_type: this.dns_resolve_type, dns_resolve_server: this.dns_resolve_server, dns_last_result: this.dns_last_result, - pushToken: this.pushToken, + proxyId: this.proxy_id, notificationIDList, tags: tags, + mqttUsername: this.mqttUsername, + mqttPassword: this.mqttPassword, + mqttTopic: this.mqttTopic, + mqttSuccessMessage: this.mqttSuccessMessage }; + + if (includeSensitiveData) { + data = { + ...data, + headers: this.headers, + body: this.body, + basic_auth_user: this.basic_auth_user, + basic_auth_pass: this.basic_auth_pass, + pushToken: this.pushToken, + }; + } + + return data; } async getTags() { - return await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [this.id]); + return await R.getAll("SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [ this.id ]); } /** @@ -99,6 +114,10 @@ class Monitor extends BeanModel { return Buffer.from(user + ":" + pass).toString("base64"); } + isEnabledExpiryNotification() { + return Boolean(this.expiryNotification); + } + /** * Parse to boolean * @returns {boolean} @@ -144,7 +163,7 @@ class Monitor extends BeanModel { // undefined if not https let tlsInfo = undefined; - if (! previousBeat) { + if (!previousBeat) { previousBeat = await R.findOne("heartbeat", " monitor_id = ? ORDER BY time DESC", [ this.id, ]); @@ -162,7 +181,7 @@ class Monitor extends BeanModel { } // Duration - if (! isFirstBeat) { + if (!isFirstBeat) { bean.duration = dayjs(bean.time).diff(dayjs(previousBeat.time), "second"); } else { bean.duration = 0; @@ -181,7 +200,12 @@ class Monitor extends BeanModel { }; } - debug(`[${this.name}] Prepare Options for axios`); + const httpsAgentOptions = { + maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) + rejectUnauthorized: !this.getIgnoreTls(), + }; + + log.debug("monitor", `[${this.name}] Prepare Options for axios`); const options = { url: this.url, @@ -194,17 +218,33 @@ class Monitor extends BeanModel { ...(this.headers ? JSON.parse(this.headers) : {}), ...(basicAuthHeader), }, - httpsAgent: new https.Agent({ - maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) - rejectUnauthorized: ! this.getIgnoreTls(), - }), maxRedirects: this.maxredirects, validateStatus: (status) => { return checkStatusCode(status, this.getAcceptedStatuscodes()); }, }; - debug(`[${this.name}] Axios Request`); + if (this.proxy_id) { + const proxy = await R.load("proxy", this.proxy_id); + + if (proxy && proxy.active) { + const { httpAgent, httpsAgent } = Proxy.createAgents(proxy, { + httpsAgentOptions: httpsAgentOptions, + }); + + options.proxy = false; + options.httpAgent = httpAgent; + options.httpsAgent = httpsAgent; + } + } + + if (!options.httpsAgent) { + options.httpsAgent = new https.Agent(httpsAgentOptions); + } + + log.debug("monitor", `[${this.name}] Axios Options: ${JSON.stringify(options)}`); + log.debug("monitor", `[${this.name}] Axios Request`); + let res = await axios.request(options); bean.msg = `${res.status} - ${res.statusText}`; bean.ping = dayjs().valueOf() - startTime; @@ -212,29 +252,30 @@ class Monitor extends BeanModel { // Check certificate if https is used let certInfoStartTime = dayjs().valueOf(); if (this.getUrl()?.protocol === "https:") { - debug(`[${this.name}] Check cert`); + log.debug("monitor", `[${this.name}] Check cert`); try { let tlsInfoObject = checkCertificate(res); tlsInfo = await this.updateTlsInfo(tlsInfoObject); - if (!this.getIgnoreTls()) { - debug(`[${this.name}] call sendCertNotification`); + if (!this.getIgnoreTls() && this.isEnabledExpiryNotification()) { + log.debug("monitor", `[${this.name}] call sendCertNotification`); await this.sendCertNotification(tlsInfoObject); } } catch (e) { if (e.message !== "No TLS certificate in response") { - console.error(e.message); + log.error("monitor", "Caught error"); + log.error("monitor", e.message); } } } if (process.env.TIMELOGGER === "1") { - debug("Cert Info Query Time: " + (dayjs().valueOf() - certInfoStartTime) + "ms"); + log.debug("monitor", "Cert Info Query Time: " + (dayjs().valueOf() - certInfoStartTime) + "ms"); } - if (process.env.UPTIME_KUMA_LOG_RESPONSE_BODY_MONITOR_ID == this.id) { - console.log(res.data); + if (process.env.UPTIME_KUMA_LOG_RESPONSE_BODY_MONITOR_ID === this.id) { + log.info("monitor", res.data); } if (this.type === "http") { @@ -273,24 +314,24 @@ class Monitor extends BeanModel { let dnsRes = await dnsResolve(this.hostname, this.dns_resolve_server, this.dns_resolve_type); bean.ping = dayjs().valueOf() - startTime; - if (this.dns_resolve_type == "A" || this.dns_resolve_type == "AAAA" || this.dns_resolve_type == "TXT") { + if (this.dns_resolve_type === "A" || this.dns_resolve_type === "AAAA" || this.dns_resolve_type === "TXT") { dnsMessage += "Records: "; dnsMessage += dnsRes.join(" | "); - } else if (this.dns_resolve_type == "CNAME" || this.dns_resolve_type == "PTR") { + } else if (this.dns_resolve_type === "CNAME" || this.dns_resolve_type === "PTR") { dnsMessage = dnsRes[0]; - } else if (this.dns_resolve_type == "CAA") { + } else if (this.dns_resolve_type === "CAA") { dnsMessage = dnsRes[0].issue; - } else if (this.dns_resolve_type == "MX") { + } else if (this.dns_resolve_type === "MX") { dnsRes.forEach(record => { dnsMessage += `Hostname: ${record.exchange} - Priority: ${record.priority} | `; }); dnsMessage = dnsMessage.slice(0, -2); - } else if (this.dns_resolve_type == "NS") { + } else if (this.dns_resolve_type === "NS") { dnsMessage += "Servers: "; dnsMessage += dnsRes.join(" | "); - } else if (this.dns_resolve_type == "SOA") { + } else if (this.dns_resolve_type === "SOA") { dnsMessage += `NS-Name: ${dnsRes.nsname} | Hostmaster: ${dnsRes.hostmaster} | Serial: ${dnsRes.serial} | Refresh: ${dnsRes.refresh} | Retry: ${dnsRes.retry} | Expire: ${dnsRes.expire} | MinTTL: ${dnsRes.minttl}`; - } else if (this.dns_resolve_type == "SRV") { + } else if (this.dns_resolve_type === "SRV") { dnsRes.forEach(record => { dnsMessage += `Name: ${record.name} | Port: ${record.port} | Priority: ${record.priority} | Weight: ${record.weight} | `; }); @@ -314,7 +355,7 @@ class Monitor extends BeanModel { time ]); - debug("heartbeatCount" + heartbeatCount + " " + time); + log.debug("monitor", "heartbeatCount" + heartbeatCount + " " + time); if (heartbeatCount <= 0) { // Fix #922, since previous heartbeat could be inserted by api, it should get from database @@ -345,7 +386,7 @@ class Monitor extends BeanModel { }, httpsAgent: new https.Agent({ maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) - rejectUnauthorized: ! this.getIgnoreTls(), + rejectUnauthorized: !this.getIgnoreTls(), }), maxRedirects: this.maxredirects, validateStatus: (status) => { @@ -367,7 +408,14 @@ class Monitor extends BeanModel { } else { throw new Error("Server not found on Steam"); } - + } else if (this.type === "mqtt") { + bean.msg = await mqttAsync(this.hostname, this.mqttTopic, this.mqttSuccessMessage, { + port: this.port, + username: this.mqttUsername, + password: this.mqttPassword, + interval: this.interval, + }); + bean.status = UP; } else { bean.msg = "Unknown Monitor Type"; bean.status = PENDING; @@ -398,7 +446,7 @@ class Monitor extends BeanModel { } } - debug(`[${this.name}] Check isImportant`); + log.debug("monitor", `[${this.name}] Check isImportant`); let isImportant = Monitor.isImportantBeat(isFirstBeat, previousBeat?.status, bean.status); // Mark as important if status changed, ignore pending pings, @@ -406,11 +454,11 @@ class Monitor extends BeanModel { if (isImportant) { bean.important = true; - debug(`[${this.name}] sendNotification`); + log.debug("monitor", `[${this.name}] sendNotification`); await Monitor.sendNotification(isFirstBeat, this, bean); // Clear Status Page Cache - debug(`[${this.name}] apicache clear`); + log.debug("monitor", `[${this.name}] apicache clear`); apicache.clear(); } else { @@ -418,33 +466,33 @@ class Monitor extends BeanModel { } if (bean.status === UP) { - console.info(`Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${beatInterval} seconds | Type: ${this.type}`); + log.info("monitor", `Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${beatInterval} seconds | Type: ${this.type}`); } else if (bean.status === PENDING) { if (this.retryInterval > 0) { beatInterval = this.retryInterval; } - console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Retry: ${retries} | Retry Interval: ${beatInterval} seconds | Type: ${this.type}`); + log.warn("monitor", `Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Retry: ${retries} | Retry Interval: ${beatInterval} seconds | Type: ${this.type}`); } else { - console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`); + log.warn("monitor", `Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`); } - debug(`[${this.name}] Send to socket`); + log.debug("monitor", `[${this.name}] Send to socket`); io.to(this.user_id).emit("heartbeat", bean.toJSON()); Monitor.sendStats(io, this.id, this.user_id); - debug(`[${this.name}] Store`); + log.debug("monitor", `[${this.name}] Store`); await R.store(bean); - debug(`[${this.name}] prometheus.update`); + log.debug("monitor", `[${this.name}] prometheus.update`); prometheus.update(bean, tlsInfo); previousBeat = bean; if (! this.isStop) { - debug(`[${this.name}] SetTimeout for next check.`); + log.debug("monitor", `[${this.name}] SetTimeout for next check.`); this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000); } else { - console.log(`[${this.name}] isStop = true, no next check.`); + log.info("monitor", `[${this.name}] isStop = true, no next check.`); } }; @@ -455,10 +503,10 @@ class Monitor extends BeanModel { } catch (e) { console.trace(e); errorLog(e, false); - console.error("Please report to https://github.com/louislam/uptime-kuma/issues"); + log.error("monitor", "Please report to https://github.com/louislam/uptime-kuma/issues"); if (! this.isStop) { - console.log("Try to restart the monitor"); + log.info("monitor", "Try to restart the monitor"); this.heartbeatInterval = setTimeout(safeBeat, this.interval * 1000); } } @@ -477,6 +525,12 @@ class Monitor extends BeanModel { stop() { clearTimeout(this.heartbeatInterval); this.isStop = true; + + this.prometheus().remove(); + } + + prometheus() { + return new Prometheus(this); } /** @@ -499,41 +553,41 @@ class Monitor extends BeanModel { * @returns {Promise} */ async updateTlsInfo(checkCertificateResult) { - let tls_info_bean = await R.findOne("monitor_tls_info", "monitor_id = ?", [ + let tlsInfoBean = await R.findOne("monitor_tls_info", "monitor_id = ?", [ this.id, ]); - if (tls_info_bean == null) { - tls_info_bean = R.dispense("monitor_tls_info"); - tls_info_bean.monitor_id = this.id; + if (tlsInfoBean == null) { + tlsInfoBean = R.dispense("monitor_tls_info"); + tlsInfoBean.monitor_id = this.id; } else { // Clear sent history if the cert changed. try { - let oldCertInfo = JSON.parse(tls_info_bean.info_json); + let oldCertInfo = JSON.parse(tlsInfoBean.info_json); let isValidObjects = oldCertInfo && oldCertInfo.certInfo && checkCertificateResult && checkCertificateResult.certInfo; if (isValidObjects) { if (oldCertInfo.certInfo.fingerprint256 !== checkCertificateResult.certInfo.fingerprint256) { - debug("Resetting sent_history"); + log.debug("monitor", "Resetting sent_history"); await R.exec("DELETE FROM notification_sent_history WHERE type = 'certificate' AND monitor_id = ?", [ this.id ]); } else { - debug("No need to reset sent_history"); - debug(oldCertInfo.certInfo.fingerprint256); - debug(checkCertificateResult.certInfo.fingerprint256); + log.debug("monitor", "No need to reset sent_history"); + log.debug("monitor", oldCertInfo.certInfo.fingerprint256); + log.debug("monitor", checkCertificateResult.certInfo.fingerprint256); } } else { - debug("Not valid object"); + log.debug("monitor", "Not valid object"); } } catch (e) { } } - tls_info_bean.info_json = JSON.stringify(checkCertificateResult); - await R.store(tls_info_bean); + tlsInfoBean.info_json = JSON.stringify(checkCertificateResult); + await R.store(tlsInfoBean); return checkCertificateResult; } @@ -547,7 +601,7 @@ class Monitor extends BeanModel { await Monitor.sendUptime(24 * 30, io, monitorID, userID); await Monitor.sendCertInfo(io, monitorID, userID); } else { - debug("No clients in the room, no need to send stats"); + log.debug("monitor", "No clients in the room, no need to send stats"); } } @@ -574,11 +628,11 @@ class Monitor extends BeanModel { } static async sendCertInfo(io, monitorID, userID) { - let tls_info = await R.findOne("monitor_tls_info", "monitor_id = ?", [ + let tlsInfo = await R.findOne("monitor_tls_info", "monitor_id = ?", [ monitorID, ]); - if (tls_info != null) { - io.to(userID).emit("certInfo", monitorID, tls_info.info_json); + if (tlsInfo != null) { + io.to(userID).emit("certInfo", monitorID, tlsInfo.info_json); } } @@ -640,7 +694,7 @@ class Monitor extends BeanModel { } else { // Handle new monitor with only one beat, because the beat's duration = 0 - let status = parseInt(await R.getCell("SELECT `status` FROM heartbeat WHERE monitor_id = ?", [ monitorID ])); + let status = parseInt(await R.getCell("SELECT `status` FROM heartbeat WHERE monitor_id = ?", [monitorID])); if (status === UP) { uptime = 1; @@ -692,10 +746,10 @@ class Monitor extends BeanModel { for (let notification of notificationList) { try { - await Notification.send(JSON.parse(notification.config), msg, await monitor.toJSON(), bean.toJSON()); + await Notification.send(JSON.parse(notification.config), msg, await monitor.toJSON(false), bean.toJSON()); } catch (e) { - console.error("Cannot send notification to " + notification.name); - console.log(e); + log.error("monitor", "Cannot send notification to " + notification.name); + log.error("monitor", e); } } } @@ -712,7 +766,7 @@ class Monitor extends BeanModel { if (tlsInfoObject && tlsInfoObject.certInfo && tlsInfoObject.certInfo.daysRemaining) { const notificationList = await Monitor.getNotificationList(this); - debug("call sendCertNotificationByTargetDays"); + log.debug("monitor", "call sendCertNotificationByTargetDays"); await this.sendCertNotificationByTargetDays(tlsInfoObject.certInfo.daysRemaining, 21, notificationList); await this.sendCertNotificationByTargetDays(tlsInfoObject.certInfo.daysRemaining, 14, notificationList); await this.sendCertNotificationByTargetDays(tlsInfoObject.certInfo.daysRemaining, 7, notificationList); @@ -722,7 +776,7 @@ class Monitor extends BeanModel { async sendCertNotificationByTargetDays(daysRemaining, targetDays, notificationList) { if (daysRemaining > targetDays) { - debug(`No need to send cert notification. ${daysRemaining} > ${targetDays}`); + log.debug("monitor", `No need to send cert notification. ${daysRemaining} > ${targetDays}`); return; } @@ -736,21 +790,21 @@ class Monitor extends BeanModel { // Sent already, no need to send again if (row) { - debug("Sent already, no need to send again"); + log.debug("monitor", "Sent already, no need to send again"); return; } let sent = false; - debug("Send certificate notification"); + log.debug("monitor", "Send certificate notification"); for (let notification of notificationList) { try { - debug("Sending to " + notification.name); + log.debug("monitor", "Sending to " + notification.name); await Notification.send(JSON.parse(notification.config), `[${this.name}][${this.url}] Certificate will be expired in ${daysRemaining} days`); sent = true; } catch (e) { - console.error("Cannot send cert notification to " + notification.name); - console.error(e); + log.error("monitor", "Cannot send cert notification to " + notification.name); + log.error("monitor", e); } } @@ -762,7 +816,7 @@ class Monitor extends BeanModel { ]); } } else { - debug("No notification, no need to send cert notification"); + log.debug("monitor", "No notification, no need to send cert notification"); } } diff --git a/server/model/proxy.js b/server/model/proxy.js new file mode 100644 index 0000000000..7ddec4349f --- /dev/null +++ b/server/model/proxy.js @@ -0,0 +1,21 @@ +const { BeanModel } = require("redbean-node/dist/bean-model"); + +class Proxy extends BeanModel { + toJSON() { + return { + id: this._id, + userId: this._user_id, + protocol: this._protocol, + host: this._host, + port: this._port, + auth: !!this._auth, + username: this._username, + password: this._password, + active: !!this._active, + default: !!this._default, + createdDate: this._created_date, + }; + } +} + +module.exports = Proxy; diff --git a/server/model/status_page.js b/server/model/status_page.js index 6f763f5867..b1befc258e 100644 --- a/server/model/status_page.js +++ b/server/model/status_page.js @@ -3,6 +3,20 @@ const { R } = require("redbean-node"); class StatusPage extends BeanModel { + static domainMappingList = { }; + + /** + * Return object like this: { "test-uptime.kuma.pet": "default" } + * @returns {Promise} + */ + static async loadDomainMappingList() { + StatusPage.domainMappingList = await R.getAssoc(` + SELECT domain, slug + FROM status_page, status_page_cname + WHERE status_page.id = status_page_cname.status_page_id + `); + } + static async sendStatusPageList(io, socket) { let result = {}; @@ -16,6 +30,57 @@ class StatusPage extends BeanModel { return list; } + async updateDomainNameList(domainNameList) { + + if (!Array.isArray(domainNameList)) { + throw new Error("Invalid array"); + } + + let trx = await R.begin(); + + await trx.exec("DELETE FROM status_page_cname WHERE status_page_id = ?", [ + this.id, + ]); + + try { + for (let domain of domainNameList) { + if (typeof domain !== "string") { + throw new Error("Invalid domain"); + } + + if (domain.trim() === "") { + continue; + } + + // If the domain name is used in another status page, delete it + await trx.exec("DELETE FROM status_page_cname WHERE domain = ?", [ + domain, + ]); + + let mapping = trx.dispense("status_page_cname"); + mapping.status_page_id = this.id; + mapping.domain = domain; + await trx.store(mapping); + } + await trx.commit(); + } catch (error) { + await trx.rollback(); + throw error; + } + } + + getDomainNameList() { + let domainList = []; + for (let domain in StatusPage.domainMappingList) { + let s = StatusPage.domainMappingList[domain]; + + if (this.slug === s) { + domainList.push(domain); + } + } + return domainList; + } + async toJSON() { return { id: this.id, @@ -26,6 +91,10 @@ class StatusPage extends BeanModel { theme: this.theme, published: !!this.published, showTags: !!this.show_tags, + domainNameList: this.getDomainNameList(), + customCSS: this.custom_css, + footerText: this.footer_text, + showPoweredBy: !!this.show_powered_by, }; } @@ -38,6 +107,9 @@ class StatusPage extends BeanModel { theme: this.theme, published: !!this.published, showTags: !!this.show_tags, + customCSS: this.custom_css, + footerText: this.footer_text, + showPoweredBy: !!this.show_powered_by, }; } diff --git a/server/model/user.js b/server/model/user.js index d1d3d200d3..b243f87fc1 100644 --- a/server/model/user.js +++ b/server/model/user.js @@ -5,17 +5,29 @@ const { R } = require("redbean-node"); class User extends BeanModel { /** - * Direct execute, no need R.store() + * + * Fix #1510, as in the context reset-password.js, there is no auto model mapping. Call this static function instead. + * @param userID * @param newPassword * @returns {Promise} */ - async resetPassword(newPassword) { + static async resetPassword(userID, newPassword) { await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [ passwordHash.generate(newPassword), - this.id + userID ]); + } + + /** + * + * @param newPassword + * @returns {Promise} + */ + async resetPassword(newPassword) { + await User.resetPassword(this.id, newPassword); this.password = newPassword; } + } module.exports = User; diff --git a/server/modules/apicache/apicache.js b/server/modules/apicache/apicache.js index 22d1fed710..25f0a54f54 100644 --- a/server/modules/apicache/apicache.js +++ b/server/modules/apicache/apicache.js @@ -68,6 +68,15 @@ function ApiCache() { instances.push(this); this.id = instances.length; + /** + * Logs a message to the console if the `DEBUG` environment variable is set. + * @param {string} a - The first argument to log. + * @param {string} b - The second argument to log. + * @param {string} c - The third argument to log. + * @param {string} d - The fourth argument to log, and so on... (optional) + * + * Generated by Trelent + */ function debug(a, b, c, d) { let arr = ["\x1b[36m[apicache]\x1b[0m", a, b, c, d].filter(function (arg) { return arg !== undefined; @@ -77,6 +86,13 @@ function ApiCache() { return (globalOptions.debug || debugEnv) && console.log.apply(null, arr); } + /** + * Returns true if the given request and response should be logged. + * @param {Object} request The HTTP request object. + * @param {Object} response The HTTP response object. + * + * Generated by Trelent + */ function shouldCacheResponse(request, response, toggle) { let opt = globalOptions; let codes = opt.statusCodes; @@ -99,6 +115,12 @@ function ApiCache() { return true; } + /** + * Adds a key to the index. + * @param {string} key The key to add. + * + * Generated by Trelent + */ function addIndexEntries(key, req) { let groupName = req.apicacheGroup; @@ -111,6 +133,13 @@ function ApiCache() { index.all.unshift(key); } + /** + * Returns a new object containing only the whitelisted headers. + * @param {Object} headers The original object of header names and values. + * @param {Array.} globalOptions.headerWhitelist An array of strings representing the whitelisted header names to keep in the output object. + * + * Generated by Trelent + */ function filterBlacklistedHeaders(headers) { return Object.keys(headers) .filter(function (key) { @@ -122,6 +151,12 @@ function ApiCache() { }, {}); } + /** + * @param {Object} headers The response headers to filter. + * @returns {Object} A new object containing only the whitelisted response headers. + * + * Generated by Trelent + */ function createCacheObject(status, headers, data, encoding) { return { status: status, @@ -132,6 +167,14 @@ function ApiCache() { }; } + /** + * Sets a cache value for the given key. + * @param {string} key The cache key to set. + * @param {*} value The cache value to set. + * @param {number} duration How long in milliseconds the cached response should be valid for (defaults to 1 hour). + * + * Generated by Trelent + */ function cacheResponse(key, value, duration) { let redis = globalOptions.redisClient; let expireCallback = globalOptions.events.expire; @@ -154,6 +197,12 @@ function ApiCache() { }, Math.min(duration, 2147483647)); } + /** + * Appends content to the response. + * @param {string|Buffer} content The content to append. + * + * Generated by Trelent + */ function accumulateContent(res, content) { if (content) { if (typeof content == "string") { @@ -179,6 +228,13 @@ function ApiCache() { } } + /** + * Monkeypatches the response object to add cache control headers and create a cache object. + * @param {Object} req - The request object. + * @param {Object} res - The response object. + * + * Generated by Trelent + */ function makeResponseCacheable(req, res, next, key, duration, strDuration, toggle) { // monkeypatch res.end to create cache object res._apicache = { @@ -245,6 +301,13 @@ function ApiCache() { next(); } + /** + * @param {Request} request + * @param {Response} response + * @returns {boolean|undefined} true if the request should be cached, false otherwise. If undefined, defaults to true. + * + * Generated by Trelent + */ function sendCachedResponse(request, response, cacheObject, toggle, next, duration) { if (toggle && !toggle(request, response)) { return next(); @@ -365,6 +428,13 @@ function ApiCache() { return this.getIndex(); }; + /** + * Converts a duration string to an integer number of milliseconds. + * @param {string} duration - The string to convert. + * @returns {number} The converted value in milliseconds, or the defaultDuration if it can't be parsed. + * + * Generated by Trelent + */ function parseDuration(duration, defaultDuration) { if (typeof duration === "number") { return duration; diff --git a/server/notification-providers/alerta.js b/server/notification-providers/alerta.js index e692b57bac..2b85d67a69 100644 --- a/server/notification-providers/alerta.js +++ b/server/notification-providers/alerta.js @@ -14,7 +14,7 @@ class Alerta extends NotificationProvider { let config = { headers: { "Content-Type": "application/json;charset=UTF-8", - "Authorization": "Key " + notification.alertaapiKey, + "Authorization": "Key " + notification.alertaApiKey, } }; let data = { @@ -40,17 +40,17 @@ class Alerta extends NotificationProvider { await axios.post(alertaUrl, postData, config); } else { let datadup = Object.assign( { - correlate: ["service_up", "service_down"], + correlate: [ "service_up", "service_down" ], event: monitorJSON["type"], group: "uptimekuma-" + monitorJSON["type"], resource: monitorJSON["name"], }, data ); - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { datadup.severity = notification.alertaAlertState; // critical datadup.text = "Service " + monitorJSON["type"] + " is down."; await axios.post(alertaUrl, datadup, config); - } else if (heartbeatJSON["status"] == UP) { + } else if (heartbeatJSON["status"] === UP) { datadup.severity = notification.alertaRecoverState; // cleaned datadup.text = "Service " + monitorJSON["type"] + " is up."; await axios.post(alertaUrl, datadup, config); diff --git a/server/notification-providers/aliyun-sms.js b/server/notification-providers/aliyun-sms.js index 6a20632005..9a14240c4d 100644 --- a/server/notification-providers/aliyun-sms.js +++ b/server/notification-providers/aliyun-sms.js @@ -64,7 +64,7 @@ class AliyunSMS extends NotificationProvider { }; let result = await axios(config); - if (result.data.Message == "OK") { + if (result.data.Message === "OK") { return true; } return false; diff --git a/server/notification-providers/apprise.js b/server/notification-providers/apprise.js index fdcd8d61be..2d795d4e50 100644 --- a/server/notification-providers/apprise.js +++ b/server/notification-providers/apprise.js @@ -1,12 +1,12 @@ const NotificationProvider = require("./notification-provider"); -const child_process = require("child_process"); +const childProcess = require("child_process"); class Apprise extends NotificationProvider { name = "apprise"; async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { - let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL]) + let s = childProcess.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL ]); let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found"; @@ -16,7 +16,7 @@ class Apprise extends NotificationProvider { return "Sent Successfully"; } - throw new Error(output) + throw new Error(output); } else { return "No output from apprise"; } diff --git a/server/notification-providers/bark.js b/server/notification-providers/bark.js index 4ebe978ad6..8920c29576 100644 --- a/server/notification-providers/bark.js +++ b/server/notification-providers/bark.js @@ -21,31 +21,26 @@ class Bark extends NotificationProvider { name = "Bark"; async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { - try { - var barkEndpoint = notification.barkEndpoint; + let barkEndpoint = notification.barkEndpoint; - // check if the endpoint has a "/" suffix, if so, delete it first - if (barkEndpoint.endsWith("/")) { - barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); - } - - if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == UP) { - let title = "UptimeKuma Monitor Up"; - return await this.postNotification(title, msg, barkEndpoint); - } + // check if the endpoint has a "/" suffix, if so, delete it first + if (barkEndpoint.endsWith("/")) { + barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1); + } - if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { - let title = "UptimeKuma Monitor Down"; - return await this.postNotification(title, msg, barkEndpoint); - } + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) { + let title = "UptimeKuma Monitor Up"; + return await this.postNotification(title, msg, barkEndpoint); + } - if (msg != null) { - let title = "UptimeKuma Message"; - return await this.postNotification(title, msg, barkEndpoint); - } + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) { + let title = "UptimeKuma Monitor Down"; + return await this.postNotification(title, msg, barkEndpoint); + } - } catch (error) { - throw error; + if (msg != null) { + let title = "UptimeKuma Message"; + return await this.postNotification(title, msg, barkEndpoint); } } diff --git a/server/notification-providers/clicksendsms.js b/server/notification-providers/clicksendsms.js index 74e2f4c590..e66b982c8e 100644 --- a/server/notification-providers/clicksendsms.js +++ b/server/notification-providers/clicksendsms.js @@ -12,7 +12,7 @@ class ClickSendSMS extends NotificationProvider { let config = { headers: { "Content-Type": "application/json", - "Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString('base64'), + "Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString("base64"), "Accept": "text/json", } }; diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js index cf08f14bfe..ef7dba0dc6 100644 --- a/server/notification-providers/dingding.js +++ b/server/notification-providers/dingding.js @@ -50,7 +50,7 @@ class DingDing extends NotificationProvider { }; let result = await axios(config); - if (result.data.errmsg == "ok") { + if (result.data.errmsg === "ok") { return true; } return false; diff --git a/server/notification-providers/discord.js b/server/notification-providers/discord.js index 881ad2113a..dd63e74b6c 100644 --- a/server/notification-providers/discord.js +++ b/server/notification-providers/discord.js @@ -17,8 +17,8 @@ class Discord extends NotificationProvider { let discordtestdata = { username: discordDisplayName, content: msg, - } - await axios.post(notification.discordWebhookUrl, discordtestdata) + }; + await axios.post(notification.discordWebhookUrl, discordtestdata); return okMsg; } @@ -35,7 +35,7 @@ class Discord extends NotificationProvider { } // If heartbeatJSON is not null, we go into the normal alerting loop. - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let discorddowndata = { username: discordDisplayName, embeds: [{ @@ -61,16 +61,16 @@ class Discord extends NotificationProvider { }, ], }], - } + }; if (notification.discordPrefixMessage) { discorddowndata.content = notification.discordPrefixMessage; } - await axios.post(notification.discordWebhookUrl, discorddowndata) + await axios.post(notification.discordWebhookUrl, discorddowndata); return okMsg; - } else if (heartbeatJSON["status"] == UP) { + } else if (heartbeatJSON["status"] === UP) { let discordupdata = { username: discordDisplayName, embeds: [{ @@ -96,17 +96,17 @@ class Discord extends NotificationProvider { }, ], }], - } + }; if (notification.discordPrefixMessage) { discordupdata.content = notification.discordPrefixMessage; } - await axios.post(notification.discordWebhookUrl, discordupdata) + await axios.post(notification.discordWebhookUrl, discordupdata); return okMsg; } } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } diff --git a/server/notification-providers/feishu.js b/server/notification-providers/feishu.js index 05fc9c1863..73781ca4e9 100644 --- a/server/notification-providers/feishu.js +++ b/server/notification-providers/feishu.js @@ -21,7 +21,7 @@ class Feishu extends NotificationProvider { return okMsg; } - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let downdata = { msg_type: "post", content: { @@ -48,7 +48,7 @@ class Feishu extends NotificationProvider { return okMsg; } - if (heartbeatJSON["status"] == UP) { + if (heartbeatJSON["status"] === UP) { let updata = { msg_type: "post", content: { diff --git a/server/notification-providers/google-chat.js b/server/notification-providers/google-chat.js index 6fb3242881..02cb4823c3 100644 --- a/server/notification-providers/google-chat.js +++ b/server/notification-providers/google-chat.js @@ -13,11 +13,11 @@ class GoogleChat extends NotificationProvider { try { // Google Chat message formatting: https://developers.google.com/chat/api/guides/message-formats/basic - let textMsg = '' + let textMsg = ""; if (heartbeatJSON && heartbeatJSON.status === UP) { - textMsg = `✅ Application is back online\n`; + textMsg = "✅ Application is back online\n"; } else if (heartbeatJSON && heartbeatJSON.status === DOWN) { - textMsg = `🔴 Application went down\n`; + textMsg = "🔴 Application went down\n"; } if (monitorJSON && monitorJSON.name) { diff --git a/server/notification-providers/gorush.js b/server/notification-providers/gorush.js index 58da5525ea..6d756e46c2 100644 --- a/server/notification-providers/gorush.js +++ b/server/notification-providers/gorush.js @@ -18,7 +18,7 @@ class Gorush extends NotificationProvider { let data = { "notifications": [ { - "tokens": [notification.gorushDeviceToken], + "tokens": [ notification.gorushDeviceToken ], "platform": platformMapping[notification.gorushPlatform], "message": msg, // Optional diff --git a/server/notification-providers/gotify.js b/server/notification-providers/gotify.js index 085261897f..0c52449397 100644 --- a/server/notification-providers/gotify.js +++ b/server/notification-providers/gotify.js @@ -15,7 +15,7 @@ class Gotify extends NotificationProvider { "message": msg, "priority": notification.gotifyPriority || 8, "title": "Uptime-Kuma", - }) + }); return okMsg; diff --git a/server/notification-providers/line.js b/server/notification-providers/line.js index 327696edd7..e594e17423 100644 --- a/server/notification-providers/line.js +++ b/server/notification-providers/line.js @@ -25,9 +25,9 @@ class Line extends NotificationProvider { "text": "Test Successful!" } ] - } - await axios.post(lineAPIUrl, testMessage, config) - } else if (heartbeatJSON["status"] == DOWN) { + }; + await axios.post(lineAPIUrl, testMessage, config); + } else if (heartbeatJSON["status"] === DOWN) { let downMessage = { "to": notification.lineUserID, "messages": [ @@ -36,9 +36,9 @@ class Line extends NotificationProvider { "text": "UptimeKuma Alert: [🔴 Down]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"] } ] - } - await axios.post(lineAPIUrl, downMessage, config) - } else if (heartbeatJSON["status"] == UP) { + }; + await axios.post(lineAPIUrl, downMessage, config); + } else if (heartbeatJSON["status"] === UP) { let upMessage = { "to": notification.lineUserID, "messages": [ @@ -47,12 +47,12 @@ class Line extends NotificationProvider { "text": "UptimeKuma Alert: [✅ Up]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"] } ] - } - await axios.post(lineAPIUrl, upMessage, config) + }; + await axios.post(lineAPIUrl, upMessage, config); } return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/lunasea.js b/server/notification-providers/lunasea.js index c41f400e2c..b53f324190 100644 --- a/server/notification-providers/lunasea.js +++ b/server/notification-providers/lunasea.js @@ -8,38 +8,38 @@ class LunaSea extends NotificationProvider { async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { let okMsg = "Sent Successfully."; - let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice + let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice; try { if (heartbeatJSON == null) { let testdata = { "title": "Uptime Kuma Alert", "body": "Testing Successful.", - } - await axios.post(lunaseadevice, testdata) + }; + await axios.post(lunaseadevice, testdata); return okMsg; } - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let downdata = { "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(lunaseadevice, downdata) + }; + await axios.post(lunaseadevice, downdata); return okMsg; } - if (heartbeatJSON["status"] == UP) { + if (heartbeatJSON["status"] === UP) { let updata = { "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(lunaseadevice, updata) + }; + await axios.post(lunaseadevice, updata); return okMsg; } } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } diff --git a/server/notification-providers/matrix.js b/server/notification-providers/matrix.js index c1054fce65..915c772d77 100644 --- a/server/notification-providers/matrix.js +++ b/server/notification-providers/matrix.js @@ -1,7 +1,7 @@ const NotificationProvider = require("./notification-provider"); const axios = require("axios"); const Crypto = require("crypto"); -const { debug } = require("../../src/util"); +const { log } = require("../../src/util"); class Matrix extends NotificationProvider { name = "matrix"; @@ -17,11 +17,11 @@ class Matrix extends NotificationProvider { .slice(0, size) ); - debug("Random String: " + randomString); + log.debug("notification", "Random String: " + randomString); const roomId = encodeURIComponent(notification.internalRoomId); - debug("Matrix Room ID: " + roomId); + log.debug("notification", "Matrix Room ID: " + roomId); try { let config = { diff --git a/server/notification-providers/mattermost.js b/server/notification-providers/mattermost.js index c2ffc23b8c..2076ad2131 100644 --- a/server/notification-providers/mattermost.js +++ b/server/notification-providers/mattermost.js @@ -15,16 +15,21 @@ class Mattermost extends NotificationProvider { let mattermostTestData = { username: mattermostUserName, text: msg, - } - await axios.post(notification.mattermostWebhookUrl, mattermostTestData) + }; + await axios.post(notification.mattermostWebhookUrl, mattermostTestData); return okMsg; } - const mattermostChannel = notification.mattermostchannel.toLowerCase(); + let mattermostChannel; + + if (typeof notification.mattermostchannel === "string") { + mattermostChannel = notification.mattermostchannel.toLowerCase(); + } + const mattermostIconEmoji = notification.mattermosticonemo; const mattermostIconUrl = notification.mattermosticonurl; - if (heartbeatJSON["status"] == DOWN) { + if (heartbeatJSON["status"] === DOWN) { let mattermostdowndata = { username: mattermostUserName, text: "Uptime Kuma Alert", @@ -68,7 +73,7 @@ class Mattermost extends NotificationProvider { mattermostdowndata ); return okMsg; - } else if (heartbeatJSON["status"] == UP) { + } else if (heartbeatJSON["status"] === UP) { let mattermostupdata = { username: mattermostUserName, text: "Uptime Kuma Alert", diff --git a/server/notification-providers/notification-provider.js b/server/notification-providers/notification-provider.js index 61c6242d7b..87687baaf2 100644 --- a/server/notification-providers/notification-provider.js +++ b/server/notification-providers/notification-provider.js @@ -25,11 +25,11 @@ class NotificationProvider { if (typeof error.response.data === "string") { msg += error.response.data; } else { - msg += JSON.stringify(error.response.data) + msg += JSON.stringify(error.response.data); } } - throw new Error(msg) + throw new Error(msg); } } diff --git a/server/notification-providers/octopush.js b/server/notification-providers/octopush.js index 9d77aa5b47..0eda940ba7 100644 --- a/server/notification-providers/octopush.js +++ b/server/notification-providers/octopush.js @@ -10,7 +10,7 @@ class Octopush extends NotificationProvider { try { // Default - V2 - if (notification.octopushVersion == 2 || !notification.octopushVersion) { + if (notification.octopushVersion === 2 || !notification.octopushVersion) { let config = { headers: { "api-key": notification.octopushAPIKey, @@ -30,14 +30,14 @@ class Octopush extends NotificationProvider { "purpose": "alert", "sender": notification.octopushSenderName }; - await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config) - } else if (notification.octopushVersion == 1) { + await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config); + } else if (notification.octopushVersion === 1) { let data = { "user_login": notification.octopushDMLogin, "api_key": notification.octopushDMAPIKey, "sms_recipients": notification.octopushDMPhoneNumber, "sms_sender": notification.octopushDMSenderName, - "sms_type": (notification.octopushDMSMSType == "sms_premium") ? "FR" : "XXX", + "sms_type": (notification.octopushDMSMSType === "sms_premium") ? "FR" : "XXX", "transactional": "1", //octopush not supporting non ascii char "sms_text": msg.replace(/[^\x00-\x7F]/g, ""), @@ -49,7 +49,7 @@ class Octopush extends NotificationProvider { }, params: data }; - await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config) + await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config); } else { throw new Error("Unknown Octopush version!"); } diff --git a/server/notification-providers/onebot.js b/server/notification-providers/onebot.js new file mode 100644 index 0000000000..6c62eccb5d --- /dev/null +++ b/server/notification-providers/onebot.js @@ -0,0 +1,45 @@ +const NotificationProvider = require("./notification-provider"); +const axios = require("axios"); + +class OneBot extends NotificationProvider { + + name = "OneBot"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + try { + let httpAddr = notification.httpAddr; + if (!httpAddr.startsWith("http")) { + httpAddr = "http://" + httpAddr; + } + if (!httpAddr.endsWith("/")) { + httpAddr += "/"; + } + let onebotAPIUrl = httpAddr + "send_msg"; + let config = { + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer " + notification.accessToken, + } + }; + let pushText = "UptimeKuma Alert: " + msg; + let data = { + "auto_escape": true, + "message": pushText, + }; + if (notification.msgType === "group") { + data["message_type"] = "group"; + data["group_id"] = notification.recieverId; + } else { + data["message_type"] = "private"; + data["user_id"] = notification.recieverId; + } + await axios.post(onebotAPIUrl, data, config); + return okMsg; + } catch (error) { + this.throwGeneralAxiosError(error); + } + } +} + +module.exports = OneBot; diff --git a/server/notification-providers/promosms.js b/server/notification-providers/promosms.js index 362ef714ad..4f7e8f9019 100644 --- a/server/notification-providers/promosms.js +++ b/server/notification-providers/promosms.js @@ -12,7 +12,7 @@ class PromoSMS extends NotificationProvider { let config = { headers: { "Content-Type": "application/json", - "Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString('base64'), + "Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString("base64"), "Accept": "text/json", } }; @@ -30,7 +30,7 @@ class PromoSMS extends NotificationProvider { let error = "Something gone wrong. Api returned " + resp.data.response.status + "."; this.throwGeneralAxiosError(error); } - + return okMsg; } catch (error) { this.throwGeneralAxiosError(error); diff --git a/server/notification-providers/pushbullet.js b/server/notification-providers/pushbullet.js index c7b824a2c6..7f7a1c8d00 100644 --- a/server/notification-providers/pushbullet.js +++ b/server/notification-providers/pushbullet.js @@ -23,26 +23,26 @@ class Pushbullet extends NotificationProvider { "type": "note", "title": "Uptime Kuma Alert", "body": "Testing Successful.", - } - await axios.post(pushbulletUrl, testdata, config) - } else if (heartbeatJSON["status"] == DOWN) { + }; + await axios.post(pushbulletUrl, testdata, config); + } else if (heartbeatJSON["status"] === DOWN) { let downdata = { "type": "note", "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(pushbulletUrl, downdata, config) - } else if (heartbeatJSON["status"] == UP) { + }; + await axios.post(pushbulletUrl, downdata, config); + } else if (heartbeatJSON["status"] === UP) { let updata = { "type": "note", "title": "UptimeKuma Alert: " + monitorJSON["name"], "body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], - } - await axios.post(pushbulletUrl, updata, config) + }; + await axios.post(pushbulletUrl, updata, config); } return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/pushdeer.js b/server/notification-providers/pushdeer.js new file mode 100644 index 0000000000..bbd83f4bf9 --- /dev/null +++ b/server/notification-providers/pushdeer.js @@ -0,0 +1,52 @@ +const NotificationProvider = require("./notification-provider"); +const axios = require("axios"); +const { DOWN, UP } = require("../../src/util"); + +class PushDeer extends NotificationProvider { + + name = "PushDeer"; + + async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { + let okMsg = "Sent Successfully."; + let pushdeerlink = "https://api2.pushdeer.com/message/push"; + + let valid = msg != null && monitorJSON != null && heartbeatJSON != null; + + let title; + if (valid && heartbeatJSON.status === UP) { + title = "## Uptime Kuma: " + monitorJSON.name + " up"; + } else if (valid && heartbeatJSON.status === DOWN) { + title = "## Uptime Kuma: " + monitorJSON.name + " down"; + } else { + title = "## Uptime Kuma Message"; + } + + let data = { + "pushkey": notification.pushdeerKey, + "text": title, + "desp": msg.replace(/\n/g, "\n\n"), + "type": "markdown", + }; + + try { + let res = await axios.post(pushdeerlink, data); + + if ("error" in res.data) { + let error = res.data.error; + this.throwGeneralAxiosError(error); + } + if (res.data.content.result.length === 0) { + let error = "Invalid PushDeer key"; + this.throwGeneralAxiosError(error); + } else if (JSON.parse(res.data.content.result[0]).success !== "ok") { + let error = "Unknown error"; + this.throwGeneralAxiosError(error); + } + return okMsg; + } catch (error) { + this.throwGeneralAxiosError(error); + } + } +} + +module.exports = PushDeer; diff --git a/server/notification-providers/pushy.js b/server/notification-providers/pushy.js index 2bb899349b..1d6e7f32f2 100644 --- a/server/notification-providers/pushy.js +++ b/server/notification-providers/pushy.js @@ -19,10 +19,10 @@ class Pushy extends NotificationProvider { "badge": 1, "sound": "ping.aiff" } - }) + }); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/rocket-chat.js b/server/notification-providers/rocket-chat.js index 25b0b945f7..fb48ce1a6f 100644 --- a/server/notification-providers/rocket-chat.js +++ b/server/notification-providers/rocket-chat.js @@ -2,7 +2,7 @@ const NotificationProvider = require("./notification-provider"); const axios = require("axios"); const Slack = require("./slack"); const { setting } = require("../util-server"); -const { getMonitorRelativeURL, UP, DOWN } = require("../../src/util"); +const { getMonitorRelativeURL, DOWN } = require("../../src/util"); class RocketChat extends NotificationProvider { diff --git a/server/notification-providers/signal.js b/server/notification-providers/signal.js index fee65754e7..677208ee63 100644 --- a/server/notification-providers/signal.js +++ b/server/notification-providers/signal.js @@ -16,10 +16,10 @@ class Signal extends NotificationProvider { }; let config = {}; - await axios.post(notification.signalURL, data, config) + await axios.post(notification.signalURL, data, config); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js index d85ee88c9c..a6a0cc0160 100644 --- a/server/notification-providers/smtp.js +++ b/server/notification-providers/smtp.js @@ -1,6 +1,6 @@ const nodemailer = require("nodemailer"); const NotificationProvider = require("./notification-provider"); -const { DOWN, UP } = require("../../src/util"); +const { DOWN } = require("../../src/util"); class SMTP extends NotificationProvider { diff --git a/server/notification-providers/techulus-push.js b/server/notification-providers/techulus-push.js index f844d17ce2..751ff4c3af 100644 --- a/server/notification-providers/techulus-push.js +++ b/server/notification-providers/techulus-push.js @@ -12,10 +12,10 @@ class TechulusPush extends NotificationProvider { await axios.post(`https://push.techulus.com/api/v1/notify/${notification.pushAPIKey}`, { "title": "Uptime-Kuma", "body": msg, - }) + }); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } } diff --git a/server/notification-providers/telegram.js b/server/notification-providers/telegram.js index 54d33bfbda..2b05762245 100644 --- a/server/notification-providers/telegram.js +++ b/server/notification-providers/telegram.js @@ -14,12 +14,12 @@ class Telegram extends NotificationProvider { chat_id: notification.telegramChatID, text: msg, }, - }) + }); return okMsg; } catch (error) { - let msg = (error.response.data.description) ? error.response.data.description : "Error without description" - throw new Error(msg) + let msg = (error.response.data.description) ? error.response.data.description : "Error without description"; + throw new Error(msg); } } } diff --git a/server/notification-providers/webhook.js b/server/notification-providers/webhook.js index 9cb361f303..d4933cf026 100644 --- a/server/notification-providers/webhook.js +++ b/server/notification-providers/webhook.js @@ -24,17 +24,17 @@ class Webhook extends NotificationProvider { config = { headers: finalData.getHeaders(), - } + }; } else { finalData = data; } - await axios.post(notification.webhookURL, finalData, config) + await axios.post(notification.webhookURL, finalData, config); return okMsg; } catch (error) { - this.throwGeneralAxiosError(error) + this.throwGeneralAxiosError(error); } } diff --git a/server/notification-providers/wecom.js b/server/notification-providers/wecom.js index 7ba8c37834..deca278cda 100644 --- a/server/notification-providers/wecom.js +++ b/server/notification-providers/wecom.js @@ -26,10 +26,10 @@ class WeCom extends NotificationProvider { composeMessage(heartbeatJSON, msg) { let title; - if (msg != null && heartbeatJSON != null && heartbeatJSON['status'] == UP) { + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === UP) { title = "UptimeKuma Monitor Up"; } - if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) { + if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] === DOWN) { title = "UptimeKuma Monitor Down"; } if (msg != null) { diff --git a/server/notification.js b/server/notification.js index 30f83b0e05..842e0e2f8d 100644 --- a/server/notification.js +++ b/server/notification.js @@ -24,19 +24,22 @@ const Feishu = require("./notification-providers/feishu"); const AliyunSms = require("./notification-providers/aliyun-sms"); const DingDing = require("./notification-providers/dingding"); const Bark = require("./notification-providers/bark"); +const { log } = require("../src/util"); const SerwerSMS = require("./notification-providers/serwersms"); const Stackfield = require("./notification-providers/stackfield"); const WeCom = require("./notification-providers/wecom"); const GoogleChat = require("./notification-providers/google-chat"); const Gorush = require("./notification-providers/gorush"); const Alerta = require("./notification-providers/alerta"); +const OneBot = require("./notification-providers/onebot"); +const PushDeer = require("./notification-providers/pushdeer"); class Notification { providerList = {}; static init() { - console.log("Prepare Notification Providers"); + log.info("notification", "Prepare Notification Providers"); this.providerList = {}; @@ -72,6 +75,8 @@ class Notification { new GoogleChat(), new Gorush(), new Alerta(), + new OneBot(), + new PushDeer(), ]; for (let item of list) { @@ -104,27 +109,27 @@ class Notification { } static async save(notification, notificationID, userID) { - let bean + let bean; if (notificationID) { bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ notificationID, userID, - ]) + ]); if (! bean) { - throw new Error("notification not found") + throw new Error("notification not found"); } } else { - bean = R.dispense("notification") + bean = R.dispense("notification"); } bean.name = notification.name; bean.user_id = userID; bean.config = JSON.stringify(notification); bean.is_default = notification.isDefault || false; - await R.store(bean) + await R.store(bean); if (notification.applyExisting) { await applyNotificationEveryMonitor(bean.id, userID); @@ -137,13 +142,13 @@ class Notification { let bean = await R.findOne("notification", " id = ? AND user_id = ? ", [ notificationID, userID, - ]) + ]); if (! bean) { - throw new Error("notification not found") + throw new Error("notification not found"); } - await R.trash(bean) + await R.trash(bean); } static checkApprise() { @@ -154,6 +159,13 @@ class Notification { } +/** + * Adds a new monitor to the database. + * @param {number} userID The ID of the user that owns this monitor. + * @param {string} name The name of this monitor. + * + * Generated by Trelent + */ async function applyNotificationEveryMonitor(notificationID, userID) { let monitors = await R.getAll("SELECT id FROM monitor WHERE user_id = ?", [ userID @@ -163,17 +175,17 @@ async function applyNotificationEveryMonitor(notificationID, userID) { let checkNotification = await R.findOne("monitor_notification", " monitor_id = ? AND notification_id = ? ", [ monitors[i].id, notificationID, - ]) + ]); if (! checkNotification) { let relation = R.dispense("monitor_notification"); relation.monitor_id = monitors[i].id; relation.notification_id = notificationID; - await R.store(relation) + await R.store(relation); } } } module.exports = { Notification, -} +}; diff --git a/server/password-hash.js b/server/password-hash.js index 91e5e1add9..a42b4df007 100644 --- a/server/password-hash.js +++ b/server/password-hash.js @@ -4,20 +4,20 @@ const saltRounds = 10; exports.generate = function (password) { return bcrypt.hashSync(password, saltRounds); -} +}; exports.verify = function (password, hash) { if (isSHA1(hash)) { - return passwordHashOld.verify(password, hash) + return passwordHashOld.verify(password, hash); } return bcrypt.compareSync(password, hash); -} +}; function isSHA1(hash) { - return (typeof hash === "string" && hash.startsWith("sha1")) + return (typeof hash === "string" && hash.startsWith("sha1")); } exports.needRehash = function (hash) { return isSHA1(hash); -} +}; diff --git a/server/ping-lite.js b/server/ping-lite.js index 0075e80bd0..5f15b6d3a0 100644 --- a/server/ping-lite.js +++ b/server/ping-lite.js @@ -8,6 +8,13 @@ const util = require("./util-server"); module.exports = Ping; +/** + * @param {string} host - The host to ping + * @param {object} [options] - Options for the ping command + * @param {array|string} [options.args] - Arguments to pass to the ping command + * + * Generated by Trelent + */ function Ping(host, options) { if (!host) { throw new Error("You must specify a host to ping!"); @@ -125,6 +132,11 @@ Ping.prototype.send = function (callback) { } }); + /** + * @param {Function} callback + * + * Generated by Trelent + */ function onEnd() { let stdout = this.stdout._stdout; let stderr = this.stderr._stderr; diff --git a/server/prometheus.js b/server/prometheus.js index f91b0a13bb..fe0896f61e 100644 --- a/server/prometheus.js +++ b/server/prometheus.js @@ -1,4 +1,5 @@ const PrometheusClient = require("prom-client"); +const { log } = require("../src/util"); const commonLabels = [ "monitor_name", @@ -8,24 +9,24 @@ const commonLabels = [ "monitor_port", ]; -const monitor_cert_days_remaining = new PrometheusClient.Gauge({ +const monitorCertDaysRemaining = new PrometheusClient.Gauge({ name: "monitor_cert_days_remaining", help: "The number of days remaining until the certificate expires", labelNames: commonLabels }); -const monitor_cert_is_valid = new PrometheusClient.Gauge({ +const monitorCertIsValid = new PrometheusClient.Gauge({ name: "monitor_cert_is_valid", help: "Is the certificate still valid? (1 = Yes, 0= No)", labelNames: commonLabels }); -const monitor_response_time = new PrometheusClient.Gauge({ +const monitorResponseTime = new PrometheusClient.Gauge({ name: "monitor_response_time", help: "Monitor Response Time (ms)", labelNames: commonLabels }); -const monitor_status = new PrometheusClient.Gauge({ +const monitorStatus = new PrometheusClient.Gauge({ name: "monitor_status", help: "Monitor Status (1 = UP, 0= DOWN)", labelNames: commonLabels @@ -48,44 +49,58 @@ class Prometheus { if (typeof tlsInfo !== "undefined") { try { - let is_valid = 0; - if (tlsInfo.valid == true) { - is_valid = 1; + let isValid; + if (tlsInfo.valid === true) { + isValid = 1; } else { - is_valid = 0; + isValid = 0; } - monitor_cert_is_valid.set(this.monitorLabelValues, is_valid); + monitorCertIsValid.set(this.monitorLabelValues, isValid); } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } try { if (tlsInfo.certInfo != null) { - monitor_cert_days_remaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining); + monitorCertDaysRemaining.set(this.monitorLabelValues, tlsInfo.certInfo.daysRemaining); } } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } } try { - monitor_status.set(this.monitorLabelValues, heartbeat.status); + monitorStatus.set(this.monitorLabelValues, heartbeat.status); } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } try { if (typeof heartbeat.ping === "number") { - monitor_response_time.set(this.monitorLabelValues, heartbeat.ping); + monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping); } else { // Is it good? - monitor_response_time.set(this.monitorLabelValues, -1); + monitorResponseTime.set(this.monitorLabelValues, -1); } } catch (e) { - console.error(e); + log.error("prometheus", "Caught error"); + log.error("prometheus", e); } } + remove() { + try { + monitorCertDaysRemaining.remove(this.monitorLabelValues); + monitorCertIsValid.remove(this.monitorLabelValues); + monitorResponseTime.remove(this.monitorLabelValues); + monitorStatus.remove(this.monitorLabelValues); + } catch (e) { + console.error(e); + } + } } module.exports = { diff --git a/server/proxy.js b/server/proxy.js new file mode 100644 index 0000000000..621f24d06e --- /dev/null +++ b/server/proxy.js @@ -0,0 +1,189 @@ +const { R } = require("redbean-node"); +const HttpProxyAgent = require("http-proxy-agent"); +const HttpsProxyAgent = require("https-proxy-agent"); +const SocksProxyAgent = require("socks-proxy-agent"); +const { debug } = require("../src/util"); +const { UptimeKumaServer } = require("./uptime-kuma-server"); + +class Proxy { + + static SUPPORTED_PROXY_PROTOCOLS = [ "http", "https", "socks", "socks5", "socks4" ] + + /** + * Saves and updates given proxy entity + * + * @param proxy + * @param proxyID + * @param userID + * @return {Promise} + */ + static async save(proxy, proxyID, userID) { + let bean; + + if (proxyID) { + bean = await R.findOne("proxy", " id = ? AND user_id = ? ", [ proxyID, userID ]); + + if (!bean) { + throw new Error("proxy not found"); + } + + } else { + bean = R.dispense("proxy"); + } + + // Make sure given proxy protocol is supported + if (!this.SUPPORTED_PROXY_PROTOCOLS.includes(proxy.protocol)) { + throw new Error(` + Unsupported proxy protocol "${proxy.protocol}. + Supported protocols are ${this.SUPPORTED_PROXY_PROTOCOLS.join(", ")}."` + ); + } + + // When proxy is default update deactivate old default proxy + if (proxy.default) { + await R.exec("UPDATE proxy SET `default` = 0 WHERE `default` = 1"); + } + + bean.user_id = userID; + bean.protocol = proxy.protocol; + bean.host = proxy.host; + bean.port = proxy.port; + bean.auth = proxy.auth; + bean.username = proxy.username; + bean.password = proxy.password; + bean.active = proxy.active || true; + bean.default = proxy.default || false; + + await R.store(bean); + + if (proxy.applyExisting) { + await applyProxyEveryMonitor(bean.id, userID); + } + + return bean; + } + + /** + * Deletes proxy with given id and removes it from monitors + * + * @param proxyID + * @param userID + * @return {Promise} + */ + static async delete(proxyID, userID) { + const bean = await R.findOne("proxy", " id = ? AND user_id = ? ", [ proxyID, userID ]); + + if (!bean) { + throw new Error("proxy not found"); + } + + // Delete removed proxy from monitors if exists + await R.exec("UPDATE monitor SET proxy_id = null WHERE proxy_id = ?", [ proxyID ]); + + // Delete proxy from list + await R.trash(bean); + } + + /** + * Create HTTP and HTTPS agents related with given proxy bean object + * + * @param proxy proxy bean object + * @param options http and https agent options + * @return {{httpAgent: Agent, httpsAgent: Agent}} + */ + static createAgents(proxy, options) { + const { httpAgentOptions, httpsAgentOptions } = options || {}; + let agent; + let httpAgent; + let httpsAgent; + + const proxyOptions = { + protocol: proxy.protocol, + host: proxy.host, + port: proxy.port, + }; + + if (proxy.auth) { + proxyOptions.auth = `${proxy.username}:${proxy.password}`; + } + + debug(`Proxy Options: ${JSON.stringify(proxyOptions)}`); + debug(`HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`); + debug(`HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`); + + switch (proxy.protocol) { + case "http": + case "https": + httpAgent = new HttpProxyAgent({ + ...httpAgentOptions || {}, + ...proxyOptions + }); + + httpsAgent = new HttpsProxyAgent({ + ...httpsAgentOptions || {}, + ...proxyOptions, + }); + break; + case "socks": + case "socks5": + case "socks4": + agent = new SocksProxyAgent({ + ...httpAgentOptions, + ...httpsAgentOptions, + ...proxyOptions, + }); + + httpAgent = agent; + httpsAgent = agent; + break; + + default: throw new Error(`Unsupported proxy protocol provided. ${proxy.protocol}`); + } + + return { + httpAgent, + httpsAgent + }; + } + + /** + * Reload proxy settings for current monitors + * @returns {Promise} + */ + static async reloadProxy() { + const server = UptimeKumaServer.getInstance(); + + let updatedList = await R.getAssoc("SELECT id, proxy_id FROM monitor"); + + for (let monitorID in server.monitorList) { + let monitor = server.monitorList[monitorID]; + + if (updatedList[monitorID]) { + monitor.proxy_id = updatedList[monitorID].proxy_id; + } + } + } +} + +/** + * Applies given proxy id to monitors + * + * @param proxyID + * @param userID + * @return {Promise} + */ +async function applyProxyEveryMonitor(proxyID, userID) { + // Find all monitors with id and proxy id + const monitors = await R.getAll("SELECT id, proxy_id FROM monitor WHERE user_id = ?", [ userID ]); + + // Update proxy id not match with given proxy id + for (const monitor of monitors) { + if (monitor.proxy_id !== proxyID) { + await R.exec("UPDATE monitor SET proxy_id = ? WHERE id = ?", [ proxyID, monitor.id ]); + } + } +} + +module.exports = { + Proxy, +}; diff --git a/server/rate-limiter.js b/server/rate-limiter.js index 0bacc14c73..f58f16cb6c 100644 --- a/server/rate-limiter.js +++ b/server/rate-limiter.js @@ -1,5 +1,5 @@ const { RateLimiter } = require("limiter"); -const { debug } = require("../src/util"); +const { log } = require("../src/util"); class KumaRateLimiter { constructor(config) { @@ -9,7 +9,7 @@ class KumaRateLimiter { async pass(callback, num = 1) { const remainingRequests = await this.removeTokens(num); - debug("Rate Limit (remainingRequests):" + remainingRequests); + log.info("rate-limit", "remaining requests: " + remainingRequests); if (remainingRequests < 0) { if (callback) { callback({ @@ -34,6 +34,14 @@ const loginRateLimiter = new KumaRateLimiter({ errorMessage: "Too frequently, try again later." }); +const twoFaRateLimiter = new KumaRateLimiter({ + tokensPerInterval: 30, + interval: "minute", + fireImmediately: true, + errorMessage: "Too frequently, try again later." +}); + module.exports = { - loginRateLimiter + loginRateLimiter, + twoFaRateLimiter, }; diff --git a/server/routers/api-router.js b/server/routers/api-router.js index ad8870847e..578655e20d 100644 --- a/server/routers/api-router.js +++ b/server/routers/api-router.js @@ -1,20 +1,31 @@ let express = require("express"); -const { allowDevAllOrigin, getSettings, setting } = require("../util-server"); +const { allowDevAllOrigin } = require("../util-server"); const { R } = require("redbean-node"); -const server = require("../server"); const apicache = require("../modules/apicache"); const Monitor = require("../model/monitor"); const dayjs = require("dayjs"); -const { UP, flipStatus, debug } = require("../../src/util"); +const { UP, flipStatus, log } = require("../../src/util"); const StatusPage = require("../model/status_page"); +const { UptimeKumaServer } = require("../uptime-kuma-server"); let router = express.Router(); let cache = apicache.middleware; +const server = UptimeKumaServer.getInstance(); let io = server.io; -router.get("/api/entry-page", async (_, response) => { +router.get("/api/entry-page", async (request, response) => { allowDevAllOrigin(response); - response.json(server.entryPage); + + let result = { }; + + if (request.hostname in StatusPage.domainMappingList) { + result.type = "statusPageMatchedDomain"; + result.statusPageSlug = StatusPage.domainMappingList[request.hostname]; + } else { + result.type = "entryPage"; + result.entryPage = server.entryPage; + } + response.json(result); }); router.get("/api/push/:pushToken", async (request, response) => { @@ -52,8 +63,8 @@ router.get("/api/push/:pushToken", async (request, response) => { duration = dayjs(bean.time).diff(dayjs(previousHeartbeat.time), "second"); } - debug("PreviousStatus: " + previousStatus); - debug("Current Status: " + status); + log.debug("router", "PreviousStatus: " + previousStatus); + log.debug("router", "Current Status: " + status); bean.important = Monitor.isImportantBeat(isFirstBeat, previousStatus, status); bean.monitor_id = monitor.id; @@ -114,7 +125,7 @@ router.get("/api/status-page/:slug", cache("5 minutes"), async (request, respons // Public Group List const publicGroupList = []; const showTags = !!statusPage.show_tags; - debug("Show Tags???" + showTags); + const list = await R.find("group", " public = 1 AND status_page_id = ? ORDER BY weight ", [ statusPage.id ]); @@ -185,14 +196,6 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques } }); -/** - * Default is published - * @returns {Promise} - */ -async function isPublished() { - return true; -} - function send403(res, msg = "") { res.status(403).json({ "status": "fail", diff --git a/server/server.js b/server/server.js index 9a5e1028bb..5e704c33c4 100644 --- a/server/server.js +++ b/server/server.js @@ -1,3 +1,8 @@ +/* + * Uptime Kuma Server + * node "server/server.js" + * DO NOT require("./server") in other modules, it likely creates circular dependency! + */ console.log("Welcome to Uptime Kuma"); // Check Node.js Version @@ -11,89 +16,92 @@ if (nodeVersion < requiredVersion) { } const args = require("args-parser")(process.argv); -const { sleep, debug, getRandomInt, genSecret } = require("../src/util"); +const { sleep, log, getRandomInt, genSecret, debug, isDev } = require("../src/util"); const config = require("./config"); -debug(args); +log.info("server", "Welcome to Uptime Kuma"); +log.debug("server", "Arguments"); +log.debug("server", args); if (! process.env.NODE_ENV) { process.env.NODE_ENV = "production"; } -console.log("Node Env: " + process.env.NODE_ENV); +log.info("server", "Node Env: " + process.env.NODE_ENV); -console.log("Importing Node libraries"); +log.info("server", "Importing Node libraries"); const fs = require("fs"); -const http = require("http"); -const https = require("https"); -console.log("Importing 3rd-party libraries"); -debug("Importing express"); +log.info("server", "Importing 3rd-party libraries"); +log.debug("server", "Importing express"); const express = require("express"); -debug("Importing socket.io"); -const { Server } = require("socket.io"); -debug("Importing redbean-node"); +log.debug("server", "Importing redbean-node"); const { R } = require("redbean-node"); -debug("Importing jsonwebtoken"); +log.debug("server", "Importing jsonwebtoken"); const jwt = require("jsonwebtoken"); -debug("Importing http-graceful-shutdown"); +log.debug("server", "Importing http-graceful-shutdown"); const gracefulShutdown = require("http-graceful-shutdown"); -debug("Importing prometheus-api-metrics"); +log.debug("server", "Importing prometheus-api-metrics"); const prometheusAPIMetrics = require("prometheus-api-metrics"); -debug("Importing compare-versions"); +log.debug("server", "Importing compare-versions"); const compareVersions = require("compare-versions"); const { passwordStrength } = require("check-password-strength"); -debug("Importing 2FA Modules"); +log.debug("server", "Importing 2FA Modules"); const notp = require("notp"); const base32 = require("thirty-two"); -console.log("Importing this project modules"); -debug("Importing Monitor"); +const { UptimeKumaServer } = require("./uptime-kuma-server"); +const server = UptimeKumaServer.getInstance(args); +const io = module.exports.io = server.io; +const app = server.app; + +log.info("server", "Importing this project modules"); +log.debug("server", "Importing Monitor"); const Monitor = require("./model/monitor"); -debug("Importing Settings"); -const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, errorLog } = require("./util-server"); +log.debug("server", "Importing Settings"); +const { getSettings, setSettings, setting, initJWTSecret, checkLogin, startUnitTest, FBSD, errorLog, doubleCheckPassword } = require("./util-server"); -debug("Importing Notification"); +log.debug("server", "Importing Notification"); const { Notification } = require("./notification"); Notification.init(); -debug("Importing Database"); +log.debug("server", "Importing Proxy"); +const { Proxy } = require("./proxy"); + +log.debug("server", "Importing Database"); const Database = require("./database"); -debug("Importing Background Jobs"); -const { initBackgroundJobs } = require("./jobs"); -const { loginRateLimiter } = require("./rate-limiter"); +log.debug("server", "Importing Background Jobs"); +const { initBackgroundJobs, stopBackgroundJobs } = require("./jobs"); +const { loginRateLimiter, twoFaRateLimiter } = require("./rate-limiter"); const { basicAuth } = require("./auth"); const { login } = require("./auth"); const passwordHash = require("./password-hash"); const checkVersion = require("./check-version"); -console.info("Version: " + checkVersion.version); +log.info("server", "Version: " + checkVersion.version); // If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available and the unspecified IPv4 address (0.0.0.0) otherwise. // Dual-stack support for (::) -let hostname = process.env.UPTIME_KUMA_HOST || args.host; - // Also read HOST if not FreeBSD, as HOST is a system environment variable in FreeBSD -if (!hostname && !FBSD) { - hostname = process.env.HOST; -} +let hostEnv = FBSD ? null : process.env.HOST; +let hostname = args.host || process.env.UPTIME_KUMA_HOST || hostEnv; if (hostname) { - console.log("Custom hostname: " + hostname); + log.info("server", "Custom hostname: " + hostname); } -const port = parseInt(process.env.UPTIME_KUMA_PORT || process.env.PORT || args.port || 3001); +const port = [ args.port, process.env.UPTIME_KUMA_PORT, process.env.PORT, 3001 ] + .map(portValue => parseInt(portValue)) + .find(portValue => !isNaN(portValue)); -// SSL -const sslKey = process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || args["ssl-key"] || undefined; -const sslCert = process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || args["ssl-cert"] || undefined; const disableFrameSameOrigin = !!process.env.UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN || args["disable-frame-sameorigin"] || false; +const cloudflaredToken = args["cloudflared-token"] || process.env.UPTIME_KUMA_CLOUDFLARED_TOKEN || undefined; // 2FA / notp verification defaults -const twofa_verification_opts = { +const twoFAVerifyOptions = { "window": 1, "time": 30 }; @@ -105,34 +113,17 @@ const twofa_verification_opts = { const testMode = !!args["test"] || false; if (config.demoMode) { - console.log("==== Demo Mode ===="); -} - -console.log("Creating express and socket.io instance"); -const app = express(); - -let server; - -if (sslKey && sslCert) { - console.log("Server Type: HTTPS"); - server = https.createServer({ - key: fs.readFileSync(sslKey), - cert: fs.readFileSync(sslCert) - }, app); -} else { - console.log("Server Type: HTTP"); - server = http.createServer(app); + log.info("server", "==== Demo Mode ===="); } -const io = new Server(server); -module.exports.io = io; - // Must be after io instantiation -const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo } = require("./client"); +const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo, sendProxyList } = require("./client"); const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler"); const databaseSocketHandler = require("./socket-handlers/database-socket-handler"); const TwoFA = require("./2fa"); const StatusPage = require("./model/status_page"); +const { cloudflaredSocketHandler, autoStart: cloudflaredAutoStart, stop: cloudflaredStop } = require("./socket-handlers/cloudflared-socket-handler"); +const { proxySocketHandler } = require("./socket-handlers/proxy-socket-handler"); app.use(express.json()); @@ -147,6 +138,7 @@ app.use(function (req, res, next) { /** * Total WebSocket client connected to server currently, no actual use + * * @type {number} */ let totalClient = 0; @@ -157,12 +149,6 @@ let totalClient = 0; */ let jwtSecret = null; -/** - * Main monitor list - * @type {{}} - */ -let monitorList = {}; - /** * Show Setup Page * @type {boolean} @@ -180,34 +166,45 @@ try { } catch (e) { // "dist/index.html" is not necessary for development if (process.env.NODE_ENV !== "development") { - console.error("Error: Cannot find 'dist/index.html', did you install correctly?"); + log.error("server", "Error: Cannot find 'dist/index.html', did you install correctly?"); process.exit(1); } } -exports.entryPage = "dashboard"; - (async () => { Database.init(args); await initDatabase(testMode); exports.entryPage = await setting("entryPage"); + await StatusPage.loadDomainMappingList(); - console.log("Adding route"); + log.info("server", "Adding route"); // *************************** // Normal Router here // *************************** // Entry Page - app.get("/", async (_request, response) => { - if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) { + app.get("/", async (request, response) => { + debug(`Request Domain: ${request.hostname}`); + + if (request.hostname in StatusPage.domainMappingList) { + debug("This is a status page domain"); + response.send(indexHTML); + } else if (exports.entryPage && exports.entryPage.startsWith("statusPage-")) { response.redirect("/status/" + exports.entryPage.replace("statusPage-", "")); } else { response.redirect("/dashboard"); } }); + if (isDev) { + app.post("/test-webhook", async (request, response) => { + log.debug("test", request.body); + response.send("OK"); + }); + } + // Robots.txt app.get("/robots.txt", async (_request, response) => { let txt = "User-agent: *\nDisallow:"; @@ -246,7 +243,7 @@ exports.entryPage = "dashboard"; } }); - console.log("Adding socket handler"); + log.info("server", "Adding socket handler"); io.on("connection", async (socket) => { sendInfo(socket); @@ -254,7 +251,7 @@ exports.entryPage = "dashboard"; totalClient++; if (needSetup) { - console.log("Redirect to setup page"); + log.info("server", "Redirect to setup page"); socket.emit("setup"); } @@ -267,33 +264,40 @@ exports.entryPage = "dashboard"; // *************************** socket.on("loginByToken", async (token, callback) => { + log.info("auth", `Login by token. IP=${getClientIp(socket)}`); try { let decoded = jwt.verify(token, jwtSecret); - console.log("Username from JWT: " + decoded.username); + log.info("auth", "Username from JWT: " + decoded.username); let user = await R.findOne("user", " username = ? AND active = 1 ", [ decoded.username, ]); if (user) { - debug("afterLogin"); - + log.debug("auth", "afterLogin"); afterLogin(socket, user); + log.debug("auth", "afterLogin ok"); - debug("afterLogin ok"); + log.info("auth", `Successfully logged in user ${decoded.username}. IP=${getClientIp(socket)}`); callback({ ok: true, }); } else { + + log.info("auth", `Inactive or deleted user ${decoded.username}. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "The user is inactive or deleted.", }); } } catch (error) { + + log.error("auth", `Invalid token. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "Invalid token.", @@ -303,10 +307,20 @@ exports.entryPage = "dashboard"; }); socket.on("login", async (data, callback) => { - console.log("Login"); + log.info("auth", `Login by username + password. IP=${getClientIp(socket)}`); + + // Checking + if (typeof callback !== "function") { + return; + } + + if (!data) { + return; + } // Login Rate Limit if (! await loginRateLimiter.pass(callback)) { + log.info("auth", `Too many failed requests for user ${data.username}. IP=${getClientIp(socket)}`); return; } @@ -315,6 +329,9 @@ exports.entryPage = "dashboard"; if (user) { if (user.twofa_status == 0) { afterLogin(socket, user); + + log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: true, token: jwt.sign({ @@ -324,13 +341,16 @@ exports.entryPage = "dashboard"; } if (user.twofa_status == 1 && !data.token) { + + log.info("auth", `2FA token required for user ${data.username}. IP=${getClientIp(socket)}`); + callback({ tokenRequired: true, }); } if (data.token) { - let verify = notp.totp.verify(data.token, user.twofa_secret, twofa_verification_opts); + let verify = notp.totp.verify(data.token, user.twofa_secret, twoFAVerifyOptions); if (user.twofa_last_token !== data.token && verify) { afterLogin(socket, user); @@ -340,6 +360,8 @@ exports.entryPage = "dashboard"; socket.userID, ]); + log.info("auth", `Successfully logged in user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: true, token: jwt.sign({ @@ -347,6 +369,9 @@ exports.entryPage = "dashboard"; }, jwtSecret), }); } else { + + log.warn("auth", `Invalid token provided for user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "Invalid Token!", @@ -354,6 +379,9 @@ exports.entryPage = "dashboard"; } } } else { + + log.warn("auth", `Incorrect username or password for user ${data.username}. IP=${getClientIp(socket)}`); + callback({ ok: false, msg: "Incorrect username or password.", @@ -363,14 +391,27 @@ exports.entryPage = "dashboard"; }); socket.on("logout", async (callback) => { + // Rate Limit + if (! await loginRateLimiter.pass(callback)) { + return; + } + socket.leave(socket.userID); socket.userID = null; - callback(); + + if (typeof callback === "function") { + callback(); + } }); - socket.on("prepare2FA", async (callback) => { + socket.on("prepare2FA", async (currentPassword, callback) => { try { + if (! await twoFaRateLimiter.pass(callback)) { + return; + } + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); let user = await R.findOne("user", " id = ? AND active = 1 ", [ socket.userID, @@ -405,73 +446,104 @@ exports.entryPage = "dashboard"; } catch (error) { callback({ ok: false, - msg: "Error while trying to prepare 2FA.", + msg: error.message, }); } }); - socket.on("save2FA", async (callback) => { + socket.on("save2FA", async (currentPassword, callback) => { try { + if (! await twoFaRateLimiter.pass(callback)) { + return; + } + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); await R.exec("UPDATE `user` SET twofa_status = 1 WHERE id = ? ", [ socket.userID, ]); + log.info("auth", `Saved 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: true, msg: "2FA Enabled.", }); } catch (error) { + + log.error("auth", `Error changing 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: false, - msg: "Error while trying to change 2FA.", + msg: error.message, }); } }); - socket.on("disable2FA", async (callback) => { + socket.on("disable2FA", async (currentPassword, callback) => { try { + if (! await twoFaRateLimiter.pass(callback)) { + return; + } + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); await TwoFA.disable2FA(socket.userID); + log.info("auth", `Disabled 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: true, msg: "2FA Disabled.", }); } catch (error) { + + log.error("auth", `Error disabling 2FA token. IP=${getClientIp(socket)}`); + callback({ ok: false, - msg: "Error while trying to change 2FA.", + msg: error.message, }); } }); - socket.on("verifyToken", async (token, callback) => { - let user = await R.findOne("user", " id = ? AND active = 1 ", [ - socket.userID, - ]); + socket.on("verifyToken", async (token, currentPassword, callback) => { + try { + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); - let verify = notp.totp.verify(token, user.twofa_secret, twofa_verification_opts); + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]); - if (user.twofa_last_token !== token && verify) { - callback({ - ok: true, - valid: true, - }); - } else { + let verify = notp.totp.verify(token, user.twofa_secret, twoFAVerifyOptions); + + if (user.twofa_last_token !== token && verify) { + callback({ + ok: true, + valid: true, + }); + } else { + callback({ + ok: false, + msg: "Invalid Token.", + valid: false, + }); + } + + } catch (error) { callback({ ok: false, - msg: "Invalid Token.", - valid: false, + msg: error.message, }); } }); socket.on("twoFAStatus", async (callback) => { - checkLogin(socket); - try { + checkLogin(socket); + let user = await R.findOne("user", " id = ? AND active = 1 ", [ socket.userID, ]); @@ -488,9 +560,10 @@ exports.entryPage = "dashboard"; }); } } catch (error) { + console.log(error); callback({ ok: false, - msg: "Error while trying to get 2FA status.", + msg: error.message, }); } }); @@ -551,9 +624,11 @@ exports.entryPage = "dashboard"; await updateMonitorNotification(bean.id, notificationIDList); - await sendMonitorList(socket); + await server.sendMonitorList(socket); await startMonitor(socket.userID, bean.id); + log.info("monitor", `Added Monitor: ${monitor.id} User ID: ${socket.userID}`); + callback({ ok: true, msg: "Added Successfully.", @@ -561,6 +636,9 @@ exports.entryPage = "dashboard"; }); } catch (e) { + + log.error("monitor", `Error adding Monitor: ${monitor.id} User ID: ${socket.userID}`); + callback({ ok: false, msg: e.message, @@ -579,6 +657,9 @@ exports.entryPage = "dashboard"; throw new Error("Permission denied."); } + // Reset Prometheus labels + server.monitorList[monitor.id]?.prometheus()?.remove(); + bean.name = monitor.name; bean.type = monitor.type; bean.url = monitor.url; @@ -594,12 +675,18 @@ exports.entryPage = "dashboard"; bean.port = monitor.port; bean.keyword = monitor.keyword; bean.ignoreTls = monitor.ignoreTls; + bean.expiryNotification = monitor.expiryNotification; bean.upsideDown = monitor.upsideDown; bean.maxredirects = monitor.maxredirects; bean.accepted_statuscodes_json = JSON.stringify(monitor.accepted_statuscodes); bean.dns_resolve_type = monitor.dns_resolve_type; bean.dns_resolve_server = monitor.dns_resolve_server; bean.pushToken = monitor.pushToken; + bean.proxyId = Number.isInteger(monitor.proxyId) ? monitor.proxyId : null; + bean.mqttUsername = monitor.mqttUsername; + bean.mqttPassword = monitor.mqttPassword; + bean.mqttTopic = monitor.mqttTopic; + bean.mqttSuccessMessage = monitor.mqttSuccessMessage; await R.store(bean); @@ -609,7 +696,7 @@ exports.entryPage = "dashboard"; await restartMonitor(socket.userID, bean.id); } - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, @@ -618,7 +705,7 @@ exports.entryPage = "dashboard"; }); } catch (e) { - console.error(e); + log.error("monitor", e); callback({ ok: false, msg: e.message, @@ -629,12 +716,12 @@ exports.entryPage = "dashboard"; socket.on("getMonitorList", async (callback) => { try { checkLogin(socket); - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, }); } catch (e) { - console.error(e); + log.error("monitor", e); callback({ ok: false, msg: e.message, @@ -646,7 +733,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Get Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("monitor", `Get Monitor: ${monitorID} User ID: ${socket.userID}`); let bean = await R.findOne("monitor", " id = ? AND user_id = ? ", [ monitorID, @@ -670,7 +757,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Get Monitor Beats: ${monitorID} User ID: ${socket.userID}`); + log.info("monitor", `Get Monitor Beats: ${monitorID} User ID: ${socket.userID}`); if (period == null) { throw new Error("Invalid period."); @@ -703,7 +790,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); await startMonitor(socket.userID, monitorID); - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, @@ -722,7 +809,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); await pauseMonitor(socket.userID, monitorID); - await sendMonitorList(socket); + await server.sendMonitorList(socket); callback({ ok: true, @@ -741,11 +828,11 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Delete Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("manage", `Delete Monitor: ${monitorID} User ID: ${socket.userID}`); - if (monitorID in monitorList) { - monitorList[monitorID].stop(); - delete monitorList[monitorID]; + if (monitorID in server.monitorList) { + server.monitorList[monitorID].stop(); + delete server.monitorList[monitorID]; } await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [ @@ -758,7 +845,7 @@ exports.entryPage = "dashboard"; msg: "Deleted Successfully.", }); - await sendMonitorList(socket); + await server.sendMonitorList(socket); // Clear heartbeat list on client await sendImportantHeartbeatList(socket, monitorID, true, true); @@ -936,21 +1023,13 @@ exports.entryPage = "dashboard"; throw new Error("Password is too weak. It should contain alphabetic and numeric characters. It must be at least 6 characters in length."); } - let user = await R.findOne("user", " id = ? AND active = 1 ", [ - socket.userID, - ]); - - if (user && passwordHash.verify(password.currentPassword, user.password)) { + let user = await doubleCheckPassword(socket, password.currentPassword); + await user.resetPassword(password.newPassword); - user.resetPassword(password.newPassword); - - callback({ - ok: true, - msg: "Password has been updated successfully.", - }); - } else { - throw new Error("Incorrect current password"); - } + callback({ + ok: true, + msg: "Password has been updated successfully.", + }); } catch (e) { callback({ @@ -977,10 +1056,14 @@ exports.entryPage = "dashboard"; } }); - socket.on("setSettings", async (data, callback) => { + socket.on("setSettings", async (data, currentPassword, callback) => { try { checkLogin(socket); + if (data.disableAuth) { + await doubleCheckPassword(socket, currentPassword); + } + await setSettings("general", data); exports.entryPage = data.entryPage; @@ -1077,9 +1160,10 @@ exports.entryPage = "dashboard"; let backupData = JSON.parse(uploadedJSON); - console.log(`Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`); + log.info("manage", `Importing Backup, User ID: ${socket.userID}, Version: ${backupData.version}`); let notificationListData = backupData.notificationList; + let proxyListData = backupData.proxyList; let monitorListData = backupData.monitorList; let version17x = compareVersions.compare(backupData.version, "1.7.0", ">="); @@ -1087,8 +1171,8 @@ exports.entryPage = "dashboard"; // If the import option is "overwrite" it'll clear most of the tables, except "settings" and "user" if (importHandle == "overwrite") { // Stops every monitor first, so it doesn't execute any heartbeat while importing - for (let id in monitorList) { - let monitor = monitorList[id]; + for (let id in server.monitorList) { + let monitor = server.monitorList[id]; await monitor.stop(); } await R.exec("DELETE FROM heartbeat"); @@ -1098,6 +1182,7 @@ exports.entryPage = "dashboard"; await R.exec("DELETE FROM monitor_tag"); await R.exec("DELETE FROM tag"); await R.exec("DELETE FROM monitor"); + await R.exec("DELETE FROM proxy"); } // Only starts importing if the backup file contains at least one notification @@ -1117,6 +1202,24 @@ exports.entryPage = "dashboard"; } } + // Only starts importing if the backup file contains at least one proxy + if (proxyListData && proxyListData.length >= 1) { + const proxies = await R.findAll("proxy"); + + // Loop over proxy list and save proxies + for (const proxy of proxyListData) { + const exists = proxies.find(item => item.id === proxy.id); + + // Do not process when proxy already exists in import handle is skip and keep + if ([ "skip", "keep" ].includes(importHandle) && !exists) { + return; + } + + // Save proxy as new entry if exists update exists one + await Proxy.save(proxy, exists ? proxy.id : undefined, proxy.userId); + } + } + // Only starts importing if the backup file contains at least one monitor if (monitorListData.length >= 1) { // Get every existing monitor name and puts them in one simple string @@ -1166,6 +1269,7 @@ exports.entryPage = "dashboard"; dns_resolve_type: monitorListData[i].dns_resolve_type, dns_resolve_server: monitorListData[i].dns_resolve_server, notificationIDList: {}, + proxy_id: monitorListData[i].proxy_id || null, }; if (monitorListData[i].pushToken) { @@ -1231,7 +1335,7 @@ exports.entryPage = "dashboard"; } await sendNotificationList(socket); - await sendMonitorList(socket); + await server.sendMonitorList(socket); } callback({ @@ -1251,7 +1355,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("manage", `Clear Events Monitor: ${monitorID} User ID: ${socket.userID}`); await R.exec("UPDATE heartbeat SET msg = ?, important = ? WHERE monitor_id = ? ", [ "", @@ -1277,7 +1381,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`); + log.info("manage", `Clear Heartbeats Monitor: ${monitorID} User ID: ${socket.userID}`); await R.exec("DELETE FROM heartbeat WHERE monitor_id = ?", [ monitorID @@ -1301,7 +1405,7 @@ exports.entryPage = "dashboard"; try { checkLogin(socket); - console.log(`Clear Statistics User ID: ${socket.userID}`); + log.info("manage", `Clear Statistics User ID: ${socket.userID}`); await R.exec("DELETE FROM heartbeat"); @@ -1319,37 +1423,39 @@ exports.entryPage = "dashboard"; // Status Page Socket Handler for admin only statusPageSocketHandler(socket); + cloudflaredSocketHandler(socket); databaseSocketHandler(socket); + proxySocketHandler(socket); - debug("added all socket handlers"); + log.debug("server", "added all socket handlers"); // *************************** // Better do anything after added all socket handlers here // *************************** - debug("check auto login"); + log.debug("auth", "check auto login"); if (await setting("disableAuth")) { - console.log("Disabled Auth: auto login to admin"); + log.info("auth", "Disabled Auth: auto login to admin"); afterLogin(socket, await R.findOne("user")); socket.emit("autoLogin"); } else { - debug("need auth"); + log.debug("auth", "need auth"); } }); - console.log("Init the server"); + log.info("server", "Init the server"); - server.once("error", async (err) => { + server.httpServer.once("error", async (err) => { console.error("Cannot listen: " + err.message); - await Database.close(); + await shutdownFunction(); }); - server.listen(port, hostname, () => { + server.httpServer.listen(port, hostname, () => { if (hostname) { - console.log(`Listening on ${hostname}:${port}`); + log.info("server", `Listening on ${hostname}:${port}`); } else { - console.log(`Listening on ${port}`); + log.info("server", `Listening on ${port}`); } startMonitors(); checkVersion.startInterval(); @@ -1361,8 +1467,18 @@ exports.entryPage = "dashboard"; initBackgroundJobs(args); + // Start cloudflared at the end if configured + await cloudflaredAutoStart(cloudflaredToken); + })(); +/** + * Adds or removes notifications from a monitor. + * @param {number} monitorID The ID of the monitor to add/remove notifications from. + * @param {Array.} notificationIDList An array of IDs for the notifications to add/remove. + * + * Generated by Trelent + */ async function updateMonitorNotification(monitorID, notificationIDList) { await R.exec("DELETE FROM monitor_notification WHERE monitor_id = ? ", [ monitorID, @@ -1378,6 +1494,13 @@ async function updateMonitorNotification(monitorID, notificationIDList) { } } +/** + * This function checks if the user owns a monitor with the given ID. + * @param {number} monitorID - The ID of the monitor to check ownership for. + * @param {number} userID - The ID of the user who is trying to access this data. + * + * Generated by Trelent + */ async function checkOwner(userID, monitorID) { let row = await R.getRow("SELECT id FROM monitor WHERE id = ? AND user_id = ? ", [ monitorID, @@ -1389,18 +1512,17 @@ async function checkOwner(userID, monitorID) { } } -async function sendMonitorList(socket) { - let list = await getMonitorJSONList(socket.userID); - io.to(socket.userID).emit("monitorList", list); - return list; -} - +/** + * This function is used to send the heartbeat list of a monitor. + * @param {Socket} socket - The socket object that will be used to send the data. + */ async function afterLogin(socket, user) { socket.userID = user.id; socket.join(user.id); - let monitorList = await sendMonitorList(socket); + let monitorList = await server.sendMonitorList(socket); sendNotificationList(socket); + sendProxyList(socket); await sleep(500); @@ -1419,29 +1541,20 @@ async function afterLogin(socket, user) { } } -async function getMonitorJSONList(userID) { - let result = {}; - - let monitorList = await R.find("monitor", " user_id = ? ORDER BY weight DESC, name", [ - userID, - ]); - - for (let monitor of monitorList) { - result[monitor.id] = await monitor.toJSON(); - } - - return result; -} - +/** + * Connect to the database and patch it if necessary. + * + * Generated by Trelent + */ async function initDatabase(testMode = false) { if (! fs.existsSync(Database.path)) { - console.log("Copying Database"); + log.info("server", "Copying Database"); fs.copyFileSync(Database.templatePath, Database.path); } - console.log("Connecting to the Database"); + log.info("server", "Connecting to the Database"); await Database.connect(testMode); - console.log("Connected"); + log.info("server", "Connected"); // Patch the database await Database.patch(); @@ -1451,26 +1564,33 @@ async function initDatabase(testMode = false) { ]); if (! jwtSecretBean) { - console.log("JWT secret is not found, generate one."); + log.info("server", "JWT secret is not found, generate one."); jwtSecretBean = await initJWTSecret(); - console.log("Stored JWT secret into database"); + log.info("server", "Stored JWT secret into database"); } else { - console.log("Load JWT secret from database."); + log.info("server", "Load JWT secret from database."); } // If there is no record in user table, it is a new Uptime Kuma instance, need to setup if ((await R.count("user")) === 0) { - console.log("No user, need setup"); + log.info("server", "No user, need setup"); needSetup = true; } jwtSecret = jwtSecretBean.value; } +/** + * Resume a monitor. + * @param {string} userID - The ID of the user who owns the monitor. + * @param {string} monitorID - The ID of the monitor to resume. + * + * Generated by Trelent + */ async function startMonitor(userID, monitorID) { await checkOwner(userID, monitorID); - console.log(`Resume Monitor: ${monitorID} User ID: ${userID}`); + log.info("manage", `Resume Monitor: ${monitorID} User ID: ${userID}`); await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [ monitorID, @@ -1481,11 +1601,11 @@ async function startMonitor(userID, monitorID) { monitorID, ]); - if (monitor.id in monitorList) { - monitorList[monitor.id].stop(); + if (monitor.id in server.monitorList) { + server.monitorList[monitor.id].stop(); } - monitorList[monitor.id] = monitor; + server.monitorList[monitor.id] = monitor; monitor.start(io); } @@ -1493,18 +1613,25 @@ async function restartMonitor(userID, monitorID) { return await startMonitor(userID, monitorID); } +/** + * Pause a monitor. + * @param {string} userID - The ID of the user who owns the monitor. + * @param {string} monitorID - The ID of the monitor to pause. + * + * Generated by Trelent + */ async function pauseMonitor(userID, monitorID) { await checkOwner(userID, monitorID); - console.log(`Pause Monitor: ${monitorID} User ID: ${userID}`); + log.info("manage", `Pause Monitor: ${monitorID} User ID: ${userID}`); await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [ monitorID, userID, ]); - if (monitorID in monitorList) { - monitorList[monitorID].stop(); + if (monitorID in server.monitorList) { + server.monitorList[monitorID].stop(); } } @@ -1515,7 +1642,7 @@ async function startMonitors() { let list = await R.find("monitor", " active = 1 "); for (let monitor of list) { - monitorList[monitor.id] = monitor; + server.monitorList[monitor.id] = monitor; } for (let monitor of list) { @@ -1525,24 +1652,37 @@ async function startMonitors() { } } +/** + * Stops all monitors and closes the database connection. + * @param {string} signal The signal that triggered this function to be called. + * + * Generated by Trelent + */ async function shutdownFunction(signal) { - console.log("Shutdown requested"); - console.log("Called signal: " + signal); + log.info("server", "Shutdown requested"); + log.info("server", "Called signal: " + signal); - console.log("Stopping all monitors"); - for (let id in monitorList) { - let monitor = monitorList[id]; + log.info("server", "Stopping all monitors"); + for (let id in server.monitorList) { + let monitor = server.monitorList[id]; monitor.stop(); } await sleep(2000); await Database.close(); + + stopBackgroundJobs(); + await cloudflaredStop(); +} + +function getClientIp(socket) { + return socket.client.conn.remoteAddress.replace(/^.*:/, ""); } function finalFunction() { - console.log("Graceful shutdown successful!"); + log.info("server", "Graceful shutdown successful!"); } -gracefulShutdown(server, { +gracefulShutdown(server.httpServer, { signals: "SIGINT SIGTERM", timeout: 30000, // timeout: 30 secs development: false, // not in dev mode diff --git a/server/socket-handlers/cloudflared-socket-handler.js b/server/socket-handlers/cloudflared-socket-handler.js new file mode 100644 index 0000000000..fa20dff8d4 --- /dev/null +++ b/server/socket-handlers/cloudflared-socket-handler.js @@ -0,0 +1,93 @@ +const { checkLogin, setSetting, setting, doubleCheckPassword } = require("../util-server"); +const { CloudflaredTunnel } = require("node-cloudflared-tunnel"); +const { UptimeKumaServer } = require("../uptime-kuma-server"); +const io = UptimeKumaServer.getInstance().io; + +const prefix = "cloudflared_"; +const cloudflared = new CloudflaredTunnel(); + +cloudflared.change = (running, message) => { + io.to("cloudflared").emit(prefix + "running", running); + io.to("cloudflared").emit(prefix + "message", message); +}; + +cloudflared.error = (errorMessage) => { + io.to("cloudflared").emit(prefix + "errorMessage", errorMessage); +}; + +module.exports.cloudflaredSocketHandler = (socket) => { + + socket.on(prefix + "join", async () => { + try { + checkLogin(socket); + socket.join("cloudflared"); + io.to(socket.userID).emit(prefix + "installed", cloudflared.checkInstalled()); + io.to(socket.userID).emit(prefix + "running", cloudflared.running); + io.to(socket.userID).emit(prefix + "token", await setting("cloudflaredTunnelToken")); + } catch (error) { } + }); + + socket.on(prefix + "leave", async () => { + try { + checkLogin(socket); + socket.leave("cloudflared"); + } catch (error) { } + }); + + socket.on(prefix + "start", async (token) => { + try { + checkLogin(socket); + if (token && typeof token === "string") { + await setSetting("cloudflaredTunnelToken", token); + cloudflared.token = token; + } else { + cloudflared.token = null; + } + cloudflared.start(); + } catch (error) { } + }); + + socket.on(prefix + "stop", async (currentPassword, callback) => { + try { + checkLogin(socket); + await doubleCheckPassword(socket, currentPassword); + cloudflared.stop(); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + + socket.on(prefix + "removeToken", async () => { + try { + checkLogin(socket); + await setSetting("cloudflaredTunnelToken", ""); + } catch (error) { } + }); + +}; + +module.exports.autoStart = async (token) => { + if (!token) { + token = await setting("cloudflaredTunnelToken"); + } else { + // Override the current token via args or env var + await setSetting("cloudflaredTunnelToken", token); + console.log("Use cloudflared token from args or env var"); + } + + if (token) { + console.log("Start cloudflared"); + cloudflared.token = token; + cloudflared.start(); + } +}; + +module.exports.stop = async () => { + console.log("Stop cloudflared"); + if (cloudflared) { + cloudflared.stop(); + } +}; diff --git a/server/socket-handlers/proxy-socket-handler.js b/server/socket-handlers/proxy-socket-handler.js new file mode 100644 index 0000000000..7862ff16b0 --- /dev/null +++ b/server/socket-handlers/proxy-socket-handler.js @@ -0,0 +1,54 @@ +const { checkLogin } = require("../util-server"); +const { Proxy } = require("../proxy"); +const { sendProxyList } = require("../client"); +const { UptimeKumaServer } = require("../uptime-kuma-server"); +const server = UptimeKumaServer.getInstance(); + +module.exports.proxySocketHandler = (socket) => { + socket.on("addProxy", async (proxy, proxyID, callback) => { + try { + checkLogin(socket); + + const proxyBean = await Proxy.save(proxy, proxyID, socket.userID); + await sendProxyList(socket); + + if (proxy.applyExisting) { + await Proxy.reloadProxy(); + await server.sendMonitorList(socket); + } + + callback({ + ok: true, + msg: "Saved", + id: proxyBean.id, + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); + + socket.on("deleteProxy", async (proxyID, callback) => { + try { + checkLogin(socket); + + await Proxy.delete(proxyID, socket.userID); + await sendProxyList(socket); + await Proxy.reloadProxy(); + + callback({ + ok: true, + msg: "Deleted", + }); + + } catch (e) { + callback({ + ok: false, + msg: e.message, + }); + } + }); +}; diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index 55a70d7115..20d1938239 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -1,12 +1,12 @@ const { R } = require("redbean-node"); -const { checkLogin, setSettings, setSetting } = require("../util-server"); +const { checkLogin, setSetting } = require("../util-server"); const dayjs = require("dayjs"); -const { debug } = require("../../src/util"); +const { log } = require("../../src/util"); const ImageDataURI = require("../image-data-uri"); const Database = require("../database"); const apicache = require("../modules/apicache"); const StatusPage = require("../model/status_page"); -const server = require("../server"); +const { UptimeKumaServer } = require("../uptime-kuma-server"); module.exports.statusPageSocketHandler = (socket) => { @@ -85,15 +85,35 @@ module.exports.statusPageSocketHandler = (socket) => { } }); + socket.on("getStatusPage", async (slug, callback) => { + try { + checkLogin(socket); + + let statusPage = await R.findOne("status_page", " slug = ? ", [ + slug + ]); + + if (!statusPage) { + throw new Error("No slug?"); + } + + callback({ + ok: true, + config: await statusPage.toJSON(), + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); + // Save Status Page // imgDataUrl Only Accept PNG! socket.on("saveStatusPage", async (slug, config, imgDataUrl, publicGroupList, callback) => { - try { - checkSlug(config.slug); - checkLogin(socket); - apicache.clear(); // Save Config let statusPage = await R.findOne("status_page", " slug = ? ", [ @@ -104,6 +124,8 @@ module.exports.statusPageSocketHandler = (socket) => { throw new Error("No slug?"); } + checkSlug(config.slug); + const header = "data:image/png;base64,"; // Check logo format @@ -133,10 +155,16 @@ module.exports.statusPageSocketHandler = (socket) => { //statusPage.search_engine_index = ; statusPage.show_tags = config.showTags; //statusPage.password = null; + statusPage.footer_text = config.footerText; + statusPage.custom_css = config.customCSS; + statusPage.show_powered_by = config.showPoweredBy; statusPage.modified_date = R.isoDateTime(); await R.store(statusPage); + await statusPage.updateDomainNameList(config.domainNameList); + await StatusPage.loadDomainMappingList(); + // Save Public Group List const groupIDList = []; let groupOrder = 1; @@ -177,8 +205,8 @@ module.exports.statusPageSocketHandler = (socket) => { group.id = groupBean.id; } - // Delete groups that not in the list - debug("Delete groups that not in the list"); + // Delete groups that are not in the list + log.debug("socket", "Delete groups that are not in the list"); const slots = groupIDList.map(() => "?").join(","); const data = [ @@ -187,19 +215,23 @@ module.exports.statusPageSocketHandler = (socket) => { ]; await R.exec(`DELETE FROM \`group\` WHERE id NOT IN (${slots}) AND status_page_id = ?`, data); + const server = UptimeKumaServer.getInstance(); + // Also change entry page to new slug if it is the default one, and slug is changed. if (server.entryPage === "statusPage-" + slug && statusPage.slug !== slug) { server.entryPage = "statusPage-" + statusPage.slug; await setSetting("entryPage", server.entryPage, "general"); } + apicache.clear(); + callback({ ok: true, publicGroupList, }); } catch (error) { - console.error(error); + log.error("socket", error); callback({ ok: false, @@ -254,6 +286,8 @@ module.exports.statusPageSocketHandler = (socket) => { // Delete a status page socket.on("deleteStatusPage", async (slug, callback) => { + const server = UptimeKumaServer.getInstance(); + try { checkLogin(socket); diff --git a/server/uptime-kuma-server.js b/server/uptime-kuma-server.js new file mode 100644 index 0000000000..1cc740646c --- /dev/null +++ b/server/uptime-kuma-server.js @@ -0,0 +1,90 @@ +const express = require("express"); +const https = require("https"); +const fs = require("fs"); +const http = require("http"); +const { Server } = require("socket.io"); +const { R } = require("redbean-node"); +const { log } = require("../src/util"); + +/** + * `module.exports` (alias: `server`) should be inside this class, in order to avoid circular dependency issue. + * @type {UptimeKumaServer} + */ +class UptimeKumaServer { + + /** + * + * @type {UptimeKumaServer} + */ + static instance = null; + + /** + * Main monitor list + * @type {{}} + */ + monitorList = {}; + entryPage = "dashboard"; + app = undefined; + httpServer = undefined; + io = undefined; + + static getInstance(args) { + if (UptimeKumaServer.instance == null) { + UptimeKumaServer.instance = new UptimeKumaServer(args); + } + return UptimeKumaServer.instance; + } + + constructor(args) { + // SSL + const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined; + const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined; + + log.info("server", "Creating express and socket.io instance"); + this.app = express(); + + if (sslKey && sslCert) { + log.info("server", "Server Type: HTTPS"); + this.httpServer = https.createServer({ + key: fs.readFileSync(sslKey), + cert: fs.readFileSync(sslCert) + }, this.app); + } else { + log.info("server", "Server Type: HTTP"); + this.httpServer = http.createServer(this.app); + } + + this.io = new Server(this.httpServer); + } + + async sendMonitorList(socket) { + let list = await this.getMonitorJSONList(socket.userID); + this.io.to(socket.userID).emit("monitorList", list); + return list; + } + + /** + * Get a list of monitors for the given user. + * @param {string} userID - The ID of the user to get monitors for. + * @returns {Promise} A promise that resolves to an object with monitor IDs as keys and monitor objects as values. + * + * Generated by Trelent + */ + async getMonitorJSONList(userID) { + let result = {}; + + let monitorList = await R.find("monitor", " user_id = ? ORDER BY weight DESC, name", [ + userID, + ]); + + for (let monitor of monitorList) { + result[monitor.id] = await monitor.toJSON(); + } + + return result; + } +} + +module.exports = { + UptimeKumaServer +}; diff --git a/server/util-server.js b/server/util-server.js index 2264ebea9c..7a9d3e7d1c 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -1,15 +1,15 @@ const tcpp = require("tcp-ping"); const Ping = require("./ping-lite"); const { R } = require("redbean-node"); -const { debug } = require("../src/util"); +const { log, genSecret } = require("../src/util"); const passwordHash = require("./password-hash"); -const dayjs = require("dayjs"); const { Resolver } = require("dns"); -const child_process = require("child_process"); +const childProcess = require("child_process"); const iconv = require("iconv-lite"); const chardet = require("chardet"); const fs = require("fs"); const nodeJsUtil = require("util"); +const mqtt = require("mqtt"); // From ping-lite exports.WIN = /^win/.test(process.platform); @@ -27,12 +27,12 @@ exports.initJWTSecret = async () => { "jwtSecret", ]); - if (! jwtSecretBean) { + if (!jwtSecretBean) { jwtSecretBean = R.dispense("setting"); jwtSecretBean.key = "jwtSecret"; } - jwtSecretBean.value = passwordHash.generate(dayjs() + ""); + jwtSecretBean.value = passwordHash.generate(genSecret()); await R.store(jwtSecretBean); return jwtSecretBean; }; @@ -89,11 +89,68 @@ exports.pingAsync = function (hostname, ipv6 = false) { }); }; -exports.dnsResolve = function (hostname, resolver_server, rrtype) { +exports.mqttAsync = function (hostname, topic, okMessage, options = {}) { + return new Promise((resolve, reject) => { + const { port, username, password, interval = 20 } = options; + + // Adds MQTT protocol to the hostname if not already present + if (!/^(?:http|mqtt)s?:\/\//.test(hostname)) { + hostname = "mqtt://" + hostname; + } + + const timeoutID = setTimeout(() => { + log.debug("mqtt", "MQTT timeout triggered"); + client.end(); + reject(new Error("Timeout")); + }, interval * 1000 * 0.8); + + log.debug("mqtt", "MQTT connecting"); + + let client = mqtt.connect(hostname, { + port, + username, + password + }); + + client.on("connect", () => { + log.debug("mqtt", "MQTT connected"); + + try { + log.debug("mqtt", "MQTT subscribe topic"); + client.subscribe(topic); + } catch (e) { + client.end(); + clearTimeout(timeoutID); + reject(new Error("Cannot subscribe topic")); + } + }); + + client.on("error", (error) => { + client.end(); + clearTimeout(timeoutID); + reject(error); + }); + + client.on("message", (messageTopic, message) => { + if (messageTopic == topic) { + client.end(); + clearTimeout(timeoutID); + if (okMessage != null && okMessage !== "" && message.toString() !== okMessage) { + reject(new Error(`Message Mismatch - Topic: ${messageTopic}; Message: ${message.toString()}`)); + } else { + resolve(`Topic: ${messageTopic}; Message: ${message.toString()}`); + } + } + }); + + }); +}; + +exports.dnsResolve = function (hostname, resolverServer, rrtype) { const resolver = new Resolver(); - resolver.setServers([resolver_server]); + resolver.setServers([ resolverServer ]); return new Promise((resolve, reject) => { - if (rrtype == "PTR") { + if (rrtype === "PTR") { resolver.reverse(hostname, (err, records) => { if (err) { reject(err); @@ -120,7 +177,7 @@ exports.setting = async function (key) { try { const v = JSON.parse(value); - debug(`Get Setting: ${key}: ${v}`); + log.debug("util", `Get Setting: ${key}: ${v}`); return v; } catch (e) { return value; @@ -207,7 +264,7 @@ const parseCertificateInfo = function (info) { const existingList = {}; while (link) { - debug(`[${i}] ${link.fingerprint}`); + log.debug("cert", `[${i}] ${link.fingerprint}`); if (!link.valid_from || !link.valid_to) { break; @@ -222,7 +279,7 @@ const parseCertificateInfo = function (info) { if (link.issuerCertificate == null) { break; } else if (link.issuerCertificate.fingerprint in existingList) { - debug(`[Last] ${link.issuerCertificate.fingerprint}`); + log.debug("cert", `[Last] ${link.issuerCertificate.fingerprint}`); link.issuerCertificate = null; break; } else { @@ -243,7 +300,7 @@ exports.checkCertificate = function (res) { const info = res.request.res.socket.getPeerCertificate(true); const valid = res.request.res.socket.authorized || false; - debug("Parsing Certificate Info"); + log.debug("cert", "Parsing Certificate Info"); const parsedInfo = parseCertificateInfo(info); return { @@ -258,19 +315,19 @@ exports.checkCertificate = function (res) { // Return: true if the status code is within the accepted ranges, false otherwise // Will throw an error if the provided status code is not a valid range string or code string -exports.checkStatusCode = function (status, accepted_codes) { - if (accepted_codes == null || accepted_codes.length === 0) { +exports.checkStatusCode = function (status, acceptedCodes) { + if (acceptedCodes == null || acceptedCodes.length === 0) { return false; } - for (const code_range of accepted_codes) { - const code_range_split = code_range.split("-").map(string => parseInt(string)); - if (code_range_split.length === 1) { - if (status === code_range_split[0]) { + for (const codeRange of acceptedCodes) { + const codeRangeSplit = codeRange.split("-").map(string => parseInt(string)); + if (codeRangeSplit.length === 1) { + if (status === codeRangeSplit[0]) { return true; } - } else if (code_range_split.length === 2) { - if (status >= code_range_split[0] && status <= code_range_split[1]) { + } else if (codeRangeSplit.length === 2) { + if (status >= codeRangeSplit[0] && status <= codeRangeSplit[1]) { return true; } } else { @@ -285,13 +342,13 @@ exports.getTotalClientInRoom = (io, roomName) => { const sockets = io.sockets; - if (! sockets) { + if (!sockets) { return 0; } const adapter = sockets.adapter; - if (! adapter) { + if (!adapter) { return 0; } @@ -316,15 +373,37 @@ exports.allowAllOrigin = (res) => { }; exports.checkLogin = (socket) => { - if (! socket.userID) { + if (!socket.userID) { throw new Error("You are not logged in."); } }; +/** + * For logged-in users, double-check the password + * @param socket + * @param currentPassword + * @returns {Promise} + */ +exports.doubleCheckPassword = async (socket, currentPassword) => { + if (typeof currentPassword !== "string") { + throw new Error("Wrong data type?"); + } + + let user = await R.findOne("user", " id = ? AND active = 1 ", [ + socket.userID, + ]); + + if (!user || !passwordHash.verify(currentPassword, user.password)) { + throw new Error("Incorrect current password"); + } + + return user; +}; + exports.startUnitTest = async () => { console.log("Starting unit test..."); const npm = /^win/.test(process.platform) ? "npm.cmd" : "npm"; - const child = child_process.spawn(npm, ["run", "jest"]); + const child = childProcess.spawn(npm, [ "run", "jest" ]); child.stdout.on("data", (data) => { console.log(data.toString()); @@ -346,7 +425,6 @@ exports.startUnitTest = async () => { */ exports.convertToUTF8 = (body) => { const guessEncoding = chardet.detect(body); - //debug("Guess Encoding: " + guessEncoding); const str = iconv.decode(body, guessEncoding); return str.toString(); }; diff --git a/src/App.vue b/src/App.vue index 099450d41a..f102360c11 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,12 +1,12 @@ diff --git a/src/assets/app.scss b/src/assets/app.scss index 9e37cc99b6..c3f2fa7983 100644 --- a/src/assets/app.scss +++ b/src/assets/app.scss @@ -22,6 +22,18 @@ textarea.form-control { width: 10px; } +.list-group { + border-radius: 0.75rem; + + .dark & { + .list-group-item { + background-color: $dark-bg; + color: $dark-font-color; + border-color: $dark-border-color; + } + } +} + ::-webkit-scrollbar-thumb { background: #ccc; border-radius: 20px; @@ -412,6 +424,10 @@ textarea.form-control { background-color: rgba(239, 239, 239, 0.7); border-radius: 8px; + &.no-bg { + background-color: transparent !important; + } + &:focus { outline: 0 solid #eee; background-color: rgba(245, 245, 245, 0.9); @@ -453,6 +469,10 @@ textarea.form-control { color: $primary; } +.prism-editor__textarea { + outline: none !important; +} + // Localization @import "localization.scss"; diff --git a/src/components/CertificateInfoRow.vue b/src/components/CertificateInfoRow.vue index df726eb705..3ac22f3b6b 100644 --- a/src/components/CertificateInfoRow.vue +++ b/src/components/CertificateInfoRow.vue @@ -11,23 +11,23 @@ - + - + - + - + - + diff --git a/src/components/Confirm.vue b/src/components/Confirm.vue index 391155f435..1bfe7fe4a0 100644 --- a/src/components/Confirm.vue +++ b/src/components/Confirm.vue @@ -25,7 +25,7 @@ diff --git a/src/components/CopyableInput.vue b/src/components/CopyableInput.vue index 1fe8980286..1bccfa2ceb 100644 --- a/src/components/CopyableInput.vue +++ b/src/components/CopyableInput.vue @@ -57,6 +57,7 @@ export default { default: undefined, }, }, + emits: [ "update:modelValue" ], data() { return { visibility: "password", diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue index b321fde19c..41edc4a0e7 100644 --- a/src/components/CountUp.vue +++ b/src/components/CountUp.vue @@ -5,12 +5,12 @@ diff --git a/src/components/Datetime.vue b/src/components/Datetime.vue index 1df982cb12..8662e6d8a1 100644 --- a/src/components/Datetime.vue +++ b/src/components/Datetime.vue @@ -4,12 +4,12 @@ diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index be0b122ede..245a8512c2 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -38,7 +38,7 @@ export default { beatMargin: 4, move: false, maxBeat: -1, - } + }; }, computed: { @@ -69,12 +69,12 @@ export default { if (start < 0) { // Add empty placeholder for (let i = start; i < 0; i++) { - placeholders.push(0) + placeholders.push(0); } start = 0; } - return placeholders.concat(this.beatList.slice(start)) + return placeholders.concat(this.beatList.slice(start)); }, wrapStyle() { @@ -84,7 +84,7 @@ export default { return { padding: `${topBottom}px ${leftRight}px`, width: "100%", - } + }; }, barStyle() { @@ -94,12 +94,12 @@ export default { return { transition: "all ease-in-out 0.25s", transform: `translateX(${width}px)`, - } + }; } return { transform: "translateX(0)", - } + }; }, @@ -109,7 +109,7 @@ export default { height: this.beatHeight + "px", margin: this.beatMargin + "px", "--hover-scale": this.hoverScale, - } + }; }, }, @@ -120,7 +120,7 @@ export default { setTimeout(() => { this.move = false; - }, 300) + }, 300); }, deep: true, }, @@ -162,15 +162,15 @@ export default { methods: { resize() { if (this.$refs.wrap) { - this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2)) + this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2)); } }, getBeatTitle(beat) { - return `${this.$root.datetime(beat.time)}` + ((beat.msg) ? ` - ${beat.msg}` : ``); + return `${this.$root.datetime(beat.time)}` + ((beat.msg) ? ` - ${beat.msg}` : ""); } }, -} +}; diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue index 8c03dbbda5..7a1f1a1005 100644 --- a/src/components/NotificationDialog.vue +++ b/src/components/NotificationDialog.vue @@ -69,7 +69,6 @@ @@ -278,7 +286,7 @@ export default { .dropdown-item { border-radius: 0.3rem; - padding: 2px 16px 4px 16px; + padding: 2px 16px 4px; .dark & { background: $dark-bg; @@ -286,6 +294,7 @@ export default { .dark &:hover { background: $dark-font-color; + color: $dark-font-color2; } } diff --git a/src/components/ProxyDialog.vue b/src/components/ProxyDialog.vue new file mode 100644 index 0000000000..3070925c1f --- /dev/null +++ b/src/components/ProxyDialog.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue index 37440e310b..df94eec988 100644 --- a/src/components/PublicGroupList.vue +++ b/src/components/PublicGroupList.vue @@ -145,7 +145,7 @@ export default { .mobile { .item { - padding: 13px 0 10px 0; + padding: 13px 0 10px; } } diff --git a/src/components/Tag.vue b/src/components/Tag.vue index 434358aa83..364a05c665 100644 --- a/src/components/Tag.vue +++ b/src/components/Tag.vue @@ -41,7 +41,7 @@ export default { } } } -} +}; diff --git a/src/components/settings/MonitorHistory.vue b/src/components/settings/MonitorHistory.vue index 9b5b8bd787..0092727f44 100644 --- a/src/components/settings/MonitorHistory.vue +++ b/src/components/settings/MonitorHistory.vue @@ -52,7 +52,7 @@ - - diff --git a/src/components/settings/Proxies.vue b/src/components/settings/Proxies.vue new file mode 100644 index 0000000000..4608f3aa44 --- /dev/null +++ b/src/components/settings/Proxies.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/components/settings/ReverseProxy.vue b/src/components/settings/ReverseProxy.vue new file mode 100644 index 0000000000..97db4d5974 --- /dev/null +++ b/src/components/settings/ReverseProxy.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/components/settings/Security.vue b/src/components/settings/Security.vue index ede0d90c2e..87bb745a10 100644 --- a/src/components/settings/Security.vue +++ b/src/components/settings/Security.vue @@ -4,7 +4,7 @@ + + - + - @@ -250,7 +269,6 @@ export default { data() { return { - username: "", invalidPassword: false, password: { currentPassword: "", @@ -278,10 +296,6 @@ export default { }, }, - mounted() { - this.loadUsername(); - }, - methods: { savePassword() { if (this.password.newPassword !== this.password.repeatNewPassword) { @@ -300,17 +314,16 @@ export default { } }, - loadUsername() { - const jwtPayload = this.$root.getJWTPayload(); - - if (jwtPayload) { - this.username = jwtPayload.username; - } - }, - disableAuth() { this.settings.disableAuth = true; - this.saveSettings(); + + // Need current password to disable auth + // Set it to empty if done + this.saveSettings(() => { + this.password.currentPassword = ""; + this.$root.username = null; + this.$root.socket.token = "autoLogin"; + }, this.password.currentPassword); }, enableAuth() { @@ -331,7 +344,7 @@ export default { diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue index 1a1db53cf3..11d3a1be37 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -16,6 +16,14 @@ {{ item.title }} + + + + +
@@ -75,12 +83,18 @@ export default { notifications: { title: this.$t("Notifications"), }, + "reverse-proxy": { + title: this.$t("Reverse Proxy"), + }, "monitor-history": { title: this.$t("Monitor History"), }, security: { title: this.$t("Security"), }, + proxies: { + title: this.$t("Proxies"), + }, backup: { title: this.$t("Backup"), }, @@ -115,6 +129,10 @@ export default { this.$root.getSocket().emit("getSettings", (res) => { this.settings = res.data; + if (this.settings.checkUpdate === undefined) { + this.settings.checkUpdate = true; + } + if (this.settings.searchEngineIndex === undefined) { this.settings.searchEngineIndex = false; } @@ -131,10 +149,18 @@ export default { }); }, - saveSettings() { - this.$root.getSocket().emit("setSettings", this.settings, (res) => { + /** + * Save Settings + * @param currentPassword (Optional) Only need for disableAuth to true + */ + saveSettings(callback, currentPassword) { + this.$root.getSocket().emit("setSettings", this.settings, currentPassword, (res) => { this.$root.toastRes(res); this.loadSettings(); + + if (callback) { + callback(); + } }); }, } @@ -215,4 +241,8 @@ footer { } } } + +.logout { + color: $danger !important; +} diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue index 16b4ea3307..76b66901db 100644 --- a/src/pages/StatusPage.vue +++ b/src/pages/StatusPage.vue @@ -2,49 +2,80 @@
Subject:{{ $t("Subject:") }} {{ formatSubject(cert.subject) }}
Valid To:{{ $t("Valid To:") }}
Days Remaining:{{ $t("Days Remaining:") }} {{ cert.daysRemaining }}
Issuer:{{ $t("Issuer:") }} {{ formatSubject(cert.issuer) }}
Fingerprint:{{ $t("Fingerprint:") }} {{ cert.fingerprint }}