commit 93af5dc4ba7c4fac6922d21f29527dd0f702845c Author: Colbster937 <96893162+colbychittenden@users.noreply.github.com> Date: Sun Jul 28 19:39:37 2024 -0500 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da3a634 --- /dev/null +++ b/.gitignore @@ -0,0 +1,177 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store + +testing/domains.txt \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8be66b9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,462 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Deblok Copyright (C) 2024 Deblok + This program comes with ABSOLUTELY NO WARRANTY! + diff --git a/README.md b/README.md new file mode 100644 index 0000000..bffd455 --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ + +# FilterChecker V2 +The most powerful unblocked link checker, supporting these filters: +* Lightspeed Systems +* Palo Alto Systems +* FortiGuard + +
+ +Also comes with **many** QoL (quality of life) features, including: +* Ability to be used as a User App for even better convenience +* Built-In API that can be enabled (pass `--web `, default port is 10000) +* Check all filters, or just a single filter +* Made in TypeScript, not Python, so therefore type friendly +* Showing results ephemerally is now an option +* More detailed and user-friendly outputs + +## Setup +Setting up FilterChecker V2 is as easy as pie!
+Assuming you already cloned the repo, and installed [Bun](https://bun.sh): +1. Install packages using `bun i` +2. Put your bot token in your `.env` file, use `example.env` as an example +3. Start the bot with `bun run start`, if you wish to run the API alongside, you can turn your command into `bun run start --web`, and if you want to specify a custom port, `bun run start --web 8080` + +## API Docs +**GET** `/` or `/ping`: Healthcheck, should always respond with `OK`. + +---- + +**GET/POST** `/check/[url]/results.txt`: +* If a GET request was made, it will show a FilterChecker report of all filters +* If a POST reqest was made, you'll have an option to specify what filter in a JSON format, the options are: + * `lightspeed` or `ls` for Lightspeed + * `fortiguard` or `forti` for FortiGuard + * `palo` or `paloalto` for Palo Alto + +**POST** request example: +`{"filter":"lightspeed"}`
+**POST** request example response: +``` +FilterChecker Report for youtu.be: + +Lightspeed: +LS Filter: education.videos +LS Rocket: education.videos + +``` + +**GET** request example response: +``` +FilterChecker Report for youtu.be: + +FortiGuard: +Category: Streaming Media and Download + +Lightspeed: +LS Filter: education.videos +LS Rocket: education.videos + +Palo Alto: +Risk: Low-Risk +Category: Streaming-Media +``` + +---- + +**GET/POST** `/check/[url]/results.json`: +* If a GET request was made, it will show a FilterChecker report of all filters in a JSON format. + +* If a POST reqest was made, you'll have an option to specify what filter in a JSON format, the options are: + * `lightspeed` or `ls` for Lightspeed + * `fortiguard` or `forti` for FortiGuard + * `palo` or `paloalto` for Palo Alto + +**POST** request example: +`{"filter":"lightspeed"}`
+**POST** request example response: +```json +{ + "lightspeed": [ + "education.videos", + "education.videos" + ] +} +``` +**GET** request example response: +```json +{ + "fortiguard": "Streaming Media and Download", + "lightspeed": [ + "education.videos", + "education.videos" + ], + "paloalto": [ + "Streaming-Media", + "Low-Risk" + ] +} +``` + +---- + +

+FilterChecker V2 is licensed under the Lesser GNU Public License version 2.1. diff --git a/bun.lockb b/bun.lockb new file mode 100644 index 0000000..c17e951 Binary files /dev/null and b/bun.lockb differ diff --git a/example.env b/example.env new file mode 100644 index 0000000..5e722e6 --- /dev/null +++ b/example.env @@ -0,0 +1,2 @@ +# THIS IS THE EXAMPLE.ENV FILE +BOT_TOKEN=MTE4N... \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..f5b73a5 --- /dev/null +++ b/index.html @@ -0,0 +1,302 @@ + + + + + + FilterChecker + + + +
+

FilterChecker

+
+ + +
+
+
+ +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..32ee834 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "filtercheckerv2", + "module": "src/index.ts", + "scripts": { + "start": "bun run src/index.ts" + }, + "type": "module", + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "cheerio": "^1.0.0-rc.12", + "elysia": "^1.0.16", + "ip-range-check": "^0.2.0", + "seyfert": "^1.3.3" + } +} \ No newline at end of file diff --git a/readme/lyrth.png b/readme/lyrth.png new file mode 100644 index 0000000..944f2bd Binary files /dev/null and b/readme/lyrth.png differ diff --git a/readme/preview.png b/readme/preview.png new file mode 100644 index 0000000..210f6fc Binary files /dev/null and b/readme/preview.png differ diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} diff --git a/seyfert.config.ts b/seyfert.config.ts new file mode 100644 index 0000000..f17bba6 --- /dev/null +++ b/seyfert.config.ts @@ -0,0 +1,13 @@ +// @ts-check is better +const { config } = require('seyfert'); + +module.exports = config.bot({ + token: process.env.BOT_TOKEN ?? "", + intents: ["Guilds"], + locations: { + base: "src", + output: "src", //If you are using bun, set "src" instead + commands: "commands", + events: "events" + } +}); \ No newline at end of file diff --git a/src/commands/check.ts b/src/commands/check.ts new file mode 100644 index 0000000..9c6e374 --- /dev/null +++ b/src/commands/check.ts @@ -0,0 +1,87 @@ +import { Declare, Command, type CommandContext, Options, + createStringOption, Embed, + createBooleanOption} from 'seyfert'; +import { MessageFlags } from 'seyfert/lib/types'; +import filters from "../modules/filters" +@Options( + { + url: createStringOption({ + required:true, + description: "The URL to check", + }), + filter: createStringOption({ + required:false, + + description: "The filter to check through", + choices: [ + { name: 'All', value: 'all' }, + { name: 'FortiGuard', value: 'fortiguard' }, + { name: 'Palo Alto Systems', value: 'palo' }, + { name: 'Lightspeed', value: 'lightspeed' } + ] + }), + show: createBooleanOption({ + required:false, + description: "Show the results non-ephemerally", + }), + } +) +@Declare({ + name: 'check', + description: 'Check a link against various filters', + contexts: ['BOT_DM', 'GUILD', 'PRIVATE_CHANNEL'], + integrationTypes: ['GUILD_INSTALL', 'USER_INSTALL'] +}) +export default class FilterCheckCommand extends Command { + + async run(ctx: CommandContext) { + const re = new RegExp("^(?:https?:\/\/)?(?:www\.)?([^\/]+)"); + // @ts-ignore + let url = re.exec(ctx.options.url)[1]; + + const embed = new Embed(); + embed.setColor('Green') + embed.setTitle(`Results for ${url}:`) + embed.setDescription("Loading...") + await ctx.editOrReply({ + embeds:[embed], + // @ts-ignore + flags:ctx.options.show ? undefined : MessageFlags.Ephemeral + }); + embed.setDescription("") + embed.setColor('Blue') + + // @ts-ignore + if (!ctx.options.filter || ctx.options.filter == "all") { + + let results = [await filters.fortiguard(url),await filters.lightspeed(url),await filters.palo(url)] + let formatted = ["Category: " + results[0],`LS Filter: ${results[1][0]}\nLS Rocket: ${results[1][1]}`,`Risk: ${results[2][1]}\nCategory: ${results[2][0].trim().replace(/^\s*$(?:\r\n?|\n)/gm,"")}`] + embed.addFields({name:"FortiGuard",value:formatted[0]},{name:"Lightspeed",value:formatted[1]},{name:"Palo Alto",value:formatted[2]}) + } else { + let results; + // @ts-ignore + switch (ctx.options.filter) { + case "palo": + results = await filters.palo(url); + embed.addFields({name:"Palo Alto",value:`Risk: ${results[1]}\nCategory: ${results[0].trim().replace(/^\s*$(?:\r\n?|\n)/gm,"")}`}) + break; + case "lightspeed": + results = await filters.lightspeed(url); + embed.addFields({name:"Lightspeed",value:`LS Filter: ${results[0]}\nLS Rocket: ${results[1]}`}) + break; + case "fortiguard": + results = await filters.fortiguard(url); + embed.addFields({name:"FortiGuard",value:"Category: " + results}) + break; + default: + embed.setDescription("No filter passed") + break; + } + } + + await ctx.editOrReply({ + embeds:[embed], + flags:MessageFlags.Ephemeral + }); + } +} \ No newline at end of file diff --git a/src/commands/ping.ts b/src/commands/ping.ts new file mode 100644 index 0000000..ababc36 --- /dev/null +++ b/src/commands/ping.ts @@ -0,0 +1,19 @@ +import { Declare, Command, type CommandContext } from 'seyfert'; + +@Declare({ + name: 'ping', + description: 'Show the ping with discord', + contexts: ['BOT_DM', 'GUILD', 'PRIVATE_CHANNEL'], + integrationTypes: ['GUILD_INSTALL', 'USER_INSTALL'] +}) +export default class PingCommand extends Command { + + async run(ctx: CommandContext) { + // @ts-expect-error average latency between shards + const ping = ctx.client.gateway.latency; + + await ctx.write({ + content: `Pong! Ping: \`${ping}ms\`` + }); + } +} \ No newline at end of file diff --git a/src/events/botReady.ts b/src/events/botReady.ts new file mode 100644 index 0000000..86dd5b8 --- /dev/null +++ b/src/events/botReady.ts @@ -0,0 +1,8 @@ +import { createEvent } from "seyfert"; + +export default createEvent({ + data: { once: true, name: "botReady" }, + async run(user, client) { + client.logger.info(`${user.username} is ready`); + } +}) \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..8b91208 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,12 @@ +import { Client } from 'seyfert'; + +const client = new Client(); + +if (process.argv.includes("--web")) { + require("./web/api.ts") +} +if (!process.argv.includes("--no-bot")) { +client.start().then(() => client.uploadCommands()); +} else { + setInterval(()=>{},100) +} diff --git a/src/modules/filters.ts b/src/modules/filters.ts new file mode 100644 index 0000000..05886e9 --- /dev/null +++ b/src/modules/filters.ts @@ -0,0 +1,82 @@ +import cheerio from 'cheerio'; + +// Lightspeed +async function lightspeedCategorize(num: number) { + let jFile:Blob = Bun.file("src/modules/lightspeed.json") + let catJson = await jFile.json(); + for (let i = 0; i < catJson.length;i++) { + if (catJson[i]["CategoryNumber"] == num) { + return catJson[i]["CategoryName"] + } + } + return num // No category +} + +async function lightspeed(url:string) { + let res = await fetch("https://production-archive-proxy-api.lightspeedsystems.com/archiveproxy", + { + "method":"POST", + "headers": { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'en-US,en;q=0.9', + 'authority': 'production-archive-proxy-api.lightspeedsystems.com', + 'content-type': 'application/json', + 'origin': 'https://archive.lightspeedsystems.com', + 'user-agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'x-api-key': 'onEkoztnFpTi3VG7XQEq6skQWN3aFm3h' + }, + // graphQL vvv + "body": `{"query":"\\nquery getDeviceCategorization($itemA: CustomHostLookupInput!, $itemB: CustomHostLookupInput!){\\n a: custom_HostLookup(item: $itemA) { cat}\\n b: custom_HostLookup(item: $itemB) { cat \\n }\\n}","variables":{"itemA":{"hostname":"${url}"}, "itemB":{"hostname":"${url}"}}}` + } + ); + let body= await res.json(); + let cat = [body["data"]["a"]["cat"],body["data"]["b"]["cat"]] + return [await lightspeedCategorize(cat[0]),await lightspeedCategorize(cat[1])] + +} + +// FortiGuard +async function fortiguard(url:string) { + let res = await fetch("https://www.fortiguard.com/learnmore/dns",{ + "method":"POST", + "headers": { + 'Accept': + '*/*', + 'Accept-Language': + 'en-US,en;q=0.9', + 'Authority': + 'www.fortiguard.com', + 'Content-Type': + 'application/json;charset=UTF-8', + 'Cookie': + 'cookiesession1=678A3E0F33B3CB9D7BEECD2B8A5DD036; privacy_agreement=true', + 'Origin': + 'https://www.fortiguard.com', + 'Referer': + 'https://www.fortiguard.com/services/sdns', + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' + }, + "body": `{"value": "${url}", "version": 9}` + }) + let rJson = await res.json(); + return rJson["dns"]["categoryname"] +} + +// Palo Alto + +async function palo(domain: string): Promise { + try { + const res = await fetch(`https://urlfiltering.paloaltonetworks.com/single_cr/?url=${domain}`); + const html = await res.text(); + const c = cheerio.load(html); + return [c(`*[for="id_new_category"]`).eq(2).parent().find(".form-text").text().trim(),c(`*[for="id_new_category"]`).eq(1).parent().find(".form-text").text().trim()] + } catch (error) { + console.error('Error fetching or parsing the HTML:', error); + return ''; // Return an empty string in case of error + } +} + + +export default { palo,fortiguard,lightspeed,lightspeedCategorize } \ No newline at end of file diff --git a/src/modules/lightspeed.json b/src/modules/lightspeed.json new file mode 100644 index 0000000..4d8d343 --- /dev/null +++ b/src/modules/lightspeed.json @@ -0,0 +1,738 @@ +[ + { + "CategoryNumber": -1, + "CategoryName": "not reviewed" + + }, + { + "CategoryNumber": 1, + "CategoryName": "local-allow" + + }, + { + "CategoryNumber": 2, + "CategoryName": "local-block" + + }, + {"CategoryNumber": 3,"CategoryName": "ads"}, + { + "CategoryNumber": 4, + "CategoryName": "adult" + + }, + { + "CategoryNumber": 5, + "CategoryName": "audio-video" + + }, + { + "CategoryNumber": 6, + "CategoryName": "business" + + }, + { + "CategoryNumber": 7, + "CategoryName": "errors" + + }, + { + "CategoryNumber": 8, + "CategoryName": "drugs" + + }, + { + "CategoryNumber": 9, + "CategoryName": "education" + + }, + { + "CategoryNumber": 10, + "CategoryName": "business.finance" + + }, + { + "CategoryNumber": 11, + "CategoryName": "forums" + + }, + { + "CategoryNumber": 12, + "CategoryName": "gambling" + + }, + { + "CategoryNumber": 13, + "CategoryName": "games" + + }, + { + "CategoryNumber": 14, + "CategoryName": "general" + + }, + { + "CategoryNumber": 15, + "CategoryName": "government" + + }, + { + "CategoryNumber": 16, + "CategoryName": "security.hacking" + + }, + { + "CategoryNumber": 17, + "CategoryName": "violence.hate" + + }, + { + "CategoryNumber": 18, + "CategoryName": "business.jobs" + + }, + { + "CategoryNumber": 19, + "CategoryName": "forums.mail" + + }, + { + "CategoryNumber": 20, + "CategoryName": "news" + + }, + { + "CategoryNumber": 21, + "CategoryName": "porn" + + }, + { + "CategoryNumber": 22, + "CategoryName": "porn.de" + + }, + { + "CategoryNumber": 23, + "CategoryName": "porn.es" + + }, + { + "CategoryNumber": 24, + "CategoryName": "porn.fr" + + }, + { + "CategoryNumber": 25, + "CategoryName": "porn.it" + + }, + { + "CategoryNumber": 26, + "CategoryName": "porn.jp" + + }, + { + "CategoryNumber": 27, + "CategoryName": "porn.nl" + + }, + { + "CategoryNumber": 28, + "CategoryName": "security.proxy" + + }, + { + "CategoryNumber": 29, + "CategoryName": "shopping" + + }, + { + "CategoryNumber": 30, + "CategoryName": "sports" + + }, + { + "CategoryNumber": 31, + "CategoryName": "suspicious" + + }, + { + "CategoryNumber": 32, + "CategoryName": "violence" + + }, + { + "CategoryNumber": 33, + "CategoryName": "security.warez" + + }, + { + "CategoryNumber": 34, + "CategoryName": "directory" + + }, + { + "CategoryNumber": 35, + "CategoryName": "ads.popup-ads" + + }, + { + "CategoryNumber": 36, + "CategoryName": "travel" + + }, + { + "CategoryNumber": 37, + "CategoryName": "automobile" + + }, + { + "CategoryNumber": 38, + "CategoryName": "forums.newsgroups" + + }, + { + "CategoryNumber": 39, + "CategoryName": "forums.personals" + + }, + { + "CategoryNumber": 40, + "CategoryName": "humor" + + }, + { + "CategoryNumber": 41, + "CategoryName": "education.lifestyles" + + }, + { + "CategoryNumber": 42, + "CategoryName": "alcohol" + + }, + { + "CategoryNumber": 43, + "CategoryName": "family.health" + + }, + { + "CategoryNumber": 44, + "CategoryName": "education.science" + + }, + { + "CategoryNumber": 45, + "CategoryName": "entertainment" + + }, + { + "CategoryNumber": 46, + "CategoryName": "kids_and_teens" + + }, + { + "CategoryNumber": 47, + "CategoryName": "education.arts" + + }, + { + "CategoryNumber": 48, + "CategoryName": "education.literature" + + }, + { + "CategoryNumber": 49, + "CategoryName": "music" + + }, + { + "CategoryNumber": 50, + "CategoryName": "education.music" + + }, + { + "CategoryNumber": 51, + "CategoryName": "microsoft" + + }, + { + "CategoryNumber": 52, + "CategoryName": "ads.banner-ads" + + }, + { + "CategoryNumber": 53, + "CategoryName": "ads.html-ads" + + }, + { + "CategoryNumber": 54, + "CategoryName": "ads.javascript-ads" + + }, + { + "CategoryNumber": 55, + "CategoryName": "spam" + + }, + { + "CategoryNumber": 56, + "CategoryName": "ham" + + }, + { + "CategoryNumber": 57, + "CategoryName": "computers" + + }, + { + "CategoryNumber": 58, + "CategoryName": "family.religion" + + }, + { + "CategoryNumber": 59, + "CategoryName": "world" + + }, + { + "CategoryNumber": 60, + "CategoryName": "forums.p2p" + + }, + { + "CategoryNumber": 61, + "CategoryName": "forums.im" + + }, + { + "CategoryNumber": 62, + "CategoryName": "security.spyware" + + }, + { + "CategoryNumber": 63, + "CategoryName": "security.virus" + + }, + { + "CategoryNumber": 64, + "CategoryName": "security.test" + + }, + { + "CategoryNumber": 65, + "CategoryName": "security.phishing" + + }, + { + "CategoryNumber": 66, + "CategoryName": "weapons" + + }, + { + "CategoryNumber": 67, + "CategoryName": "access-denied" + + }, + { + "CategoryNumber": 68, + "CategoryName": "law" + + }, + { + "CategoryNumber": 69, + "CategoryName": "kids_and_teens.chat" + + }, + { + "CategoryNumber": 70, + "CategoryName": "adult.language" + + }, + { + "CategoryNumber": 71, + "CategoryName": "forums.blogs" + + }, + { + "CategoryNumber": 72, + "CategoryName": "security" + + }, + { + "CategoryNumber": 73, + "CategoryName": "business.real_estate" + + }, + { + "CategoryNumber": 74, + "CategoryName": "education.games" + + }, + { + "CategoryNumber": 75, + "CategoryName": "education.social_science" + + }, + { + "CategoryNumber": 76, + "CategoryName": "family.food" + + }, + { + "CategoryNumber": 77, + "CategoryName": "kids_and_teens.animals" + + }, + { + "CategoryNumber": 78, + "CategoryName": "shopping.spam" + + }, + { + "CategoryNumber": 79, + "CategoryName": "society" + + }, + { + "CategoryNumber": 80, + "CategoryName": "education.sex" + + }, + { + "CategoryNumber": 81, + "CategoryName": "shopping.auctions" + + }, + { + "CategoryNumber": 82, + "CategoryName": "sports.fantasy" + + }, + { + "CategoryNumber": 83, + "CategoryName": "hobby" + + }, + { + "CategoryNumber": 84, + "CategoryName": "sports.youth" + + }, + { + "CategoryNumber": 85, + "CategoryName": "search" + + }, + { + "CategoryNumber": 86, + "CategoryName": "world.de" + + }, + { + "CategoryNumber": 87, + "CategoryName": "world.es" + + }, + { + "CategoryNumber": 88, + "CategoryName": "world.fr" + + }, + { + "CategoryNumber": 89, + "CategoryName": "world.it" + + }, + { + "CategoryNumber": 90, + "CategoryName": "world.jp" + + }, + { + "CategoryNumber": 91, + "CategoryName": "world.nl" + + }, + { + "CategoryNumber": 92, + "CategoryName": "world.pt" + + }, + { + "CategoryNumber": 93, + "CategoryName": "world.ru" + + }, + { + "CategoryNumber": 94, + "CategoryName": "porn.illicit" + + }, + { + "CategoryNumber": 95, + "CategoryName": "family" + + }, + { + "CategoryNumber": 96, + "CategoryName": "society.politics" + + }, + { + "CategoryNumber": 97, + "CategoryName": "society.crime" + + }, + { + "CategoryNumber": 98, + "CategoryName": "sports.martial_arts" + + }, + { + "CategoryNumber": 99, + "CategoryName": "education.history" + + }, + { + "CategoryNumber": 100, + "CategoryName": "adult.art" + + }, + { + "CategoryNumber": 101, + "CategoryName": "adult.bodyart" + + }, + { + "CategoryNumber": 102, + "CategoryName": "adult.games" + + }, + { + "CategoryNumber": 103, + "CategoryName": "adult.lifestyles" + + }, + { + "CategoryNumber": 104, + "CategoryName": "shopping.office_supplies" + + }, + { + "CategoryNumber": 105, + "CategoryName": "expired" + + }, + { + "CategoryNumber": 106, + "CategoryName": "world.pl" + + }, + { + "CategoryNumber": 107, + "CategoryName": "world.cn" + + }, + { + "CategoryNumber": 108, + "CategoryName": "world.kr" + + }, + { + "CategoryNumber": 109, + "CategoryName": "porn.pl" + + }, + { + "CategoryNumber": 110, + "CategoryName": "porn.ru" + + }, + { + "CategoryNumber": 111, + "CategoryName": "porn.pt" + + }, + { + "CategoryNumber": 112, + "CategoryName": "plagiarism" + + }, + { + "CategoryNumber": 113, + "CategoryName": "parked" + + }, + { + "CategoryNumber": 114, + "CategoryName": "suspicious.script" + + }, + { + "CategoryNumber": 115, + "CategoryName": "business.construction" + + }, + { + "CategoryNumber": 116, + "CategoryName": "security.nettools" + + }, + { + "CategoryNumber": 117, + "CategoryName": "forums.social_networking" + + }, + { + "CategoryNumber": 118, + "CategoryName": "forums.dating" + + }, + { + "CategoryNumber": 119, + "CategoryName": "business.manufacturing" + + }, + { + "CategoryNumber": 120, + "CategoryName": "G-Rated" + + }, + { + "CategoryNumber": 121, + "CategoryName": "PG-Rated" + + }, + { + "CategoryNumber": 122, + "CategoryName": "R-Rated" + + }, + { + "CategoryNumber": 123, + "CategoryName": "X-Rated" + + }, + { + "CategoryNumber": 124, + "CategoryName": "S-Rated" + + }, + { + "CategoryNumber": 125, + "CategoryName": "security.potentially_unwanted_applications" + + }, + { + "CategoryNumber": 126, + "CategoryName": "offensive" + + }, + { + "CategoryNumber": 127, + "CategoryName": "computers.filehosting" + + }, + { + "CategoryNumber": 128, + "CategoryName": "computers.consumer_electronics" + + }, + { + "CategoryNumber": 129, + "CategoryName": "education.media" + + }, + { + "CategoryNumber": 130, + "CategoryName": "security.virus_ignore" + + }, + { + "CategoryNumber": 131, + "CategoryName": "entertainment.radio_and_tv" + + }, + { + "CategoryNumber": 132, + "CategoryName": "photography" + + }, + { + "CategoryNumber": 133, + "CategoryName": "security.shorteners" + + }, + { + "CategoryNumber": 134, + "CategoryName": "security.malware" + + }, + { + "CategoryNumber": 135, + "CategoryName": "security.translators" + + }, + { + "CategoryNumber": 136, + "CategoryName": "computers.storage" + + }, + { + "CategoryNumber": 137, + "CategoryName": "violence.extremism" + + }, + { + "CategoryNumber": 138, + "CategoryName": "computers.analytics" + + }, + { + "CategoryNumber": 139, + "CategoryName": "esports" + + }, + { + "CategoryNumber": 140, + "CategoryName": "artificial-intelligence" + + }, + { + "CategoryNumber": 141, + "CategoryName": "artificial-Intelligence.generative" + + }, + { + "CategoryNumber": 142, + "CategoryName": "artificial-intelligence.detective" + + }, + { + "CategoryNumber": 200, + "CategoryName": "facebook" + + }, + { + "CategoryNumber": 201, + "CategoryName": "twitter" + + }, + { + "CategoryNumber": 202, + "CategoryName": "instagram" + + }, + { + "CategoryNumber": 203, + "CategoryName": "pinterest" + + }, + { + "CategoryNumber": 900, + "CategoryName": "education.videos" + + } + ] \ No newline at end of file diff --git a/src/modules/whois.ts b/src/modules/whois.ts new file mode 100644 index 0000000..9f871e9 --- /dev/null +++ b/src/modules/whois.ts @@ -0,0 +1,27 @@ +import ipRangeCheck from 'ip-range-check'; + +export async function getRDAP(ipv4Address: string): Promise { + try { + const response = await fetch('https://data.iana.org/rdap/ipv4.json'); + if (!response.ok) { + throw new Error('Failed to fetch RDAP data'); + } + + const rdapData = await response.json(); + const ipv4Services: Array> = rdapData.services; + + for (const service of ipv4Services) { + const cidrRanges: Array = service[0] as Array; + const endpoints: Array = service[1] as Array; + + if (ipRangeCheck(ipv4Address, cidrRanges)) { + return endpoints[0]; // usually https + } + } + + return null; + } catch (error) { + console.error('Error fetching RDAP data:', error); + return null; + } +} \ No newline at end of file diff --git a/src/web/api.ts b/src/web/api.ts new file mode 100644 index 0000000..74de777 --- /dev/null +++ b/src/web/api.ts @@ -0,0 +1,100 @@ +import Elysia from "elysia"; +import filters from "../modules/filters" +import { join } from "path"; +import { readFile } from "fs/promises"; +const app = new Elysia(); +app.get("/", async () => { + const filePath = join(import.meta.dir, "../../index.html"); + const fileContent = await readFile(filePath); + return new Response(fileContent, { headers: { "Content-Type": "text/html" } }); +}); +app.get("/api/",()=>{ + return "OK" +}) +app.get("/api/ping",()=>{ + return "OK" +}) + +app.get("/api/check/:url/results.txt",async ({ params })=>{ + let url = params.url + let results = [await filters.fortiguard(url),await filters.lightspeed(url),await filters.palo(url)] + let formatted = ["FortiGuard:\nCategory: " + results[0] + "\n",`Lightspeed:\nLS Filter: ${results[1][0]}\nLS Rocket: ${results[1][1]}\n`,`Palo Alto:\nRisk: ${results[2][1]}\nCategory: ${results[2][0].trim().replace(/^\s*$(?:\r\n?|\n)/gm,"")}\n`] + return `FilterChecker Report for ${url}:\n\n${formatted.join("\n")}` +}) + +app.get("/api/check/:url/results.json",async ({ params })=>{ + let url = params.url + let results = [await filters.fortiguard(url),await filters.lightspeed(url),await filters.palo(url)] + return {"fortiguard":results[0],"lightspeed":results[1],"paloalto":results[2]} +}); +app.post("/check/:url/results.txt",async ({ params,body,set })=>{ + let _:any = body + let bj = {"filter": "all"}; + try { + bj = JSON.parse(_) + } catch { + set.status = 400; + return "Bad JSON" + } + + let url = params.url + if (bj.filter == "all") { + let results = [await filters.fortiguard(url),await filters.lightspeed(url),await filters.palo(url)] + let formatted = ["FortiGuard:\nCategory: " + results[0] + "\n",`Lightspeed:\nLS Filter: ${results[1][0]}\nLS Rocket: ${results[1][1]}\n`,`Palo Alto:\nRisk: ${results[2][1]}\nCategory: ${results[2][0].trim().replace(/^\s*$(?:\r\n?|\n)/gm,"")}\n`] + return `FilterChecker Report for ${url}:\n\n${formatted.join("\n")}` + } else { + let results; let formatted; + switch (bj.filter) { + case ("fortiguard" || "forti"): + results = await filters.fortiguard(url) + formatted = "FortiGuard:\nCategory: " + results[0] + return `FilterChecker Report for ${url}:\n\n${formatted}` + case ("lightspeed" || "ls"): + results = await filters.lightspeed(url) + formatted = `Lightspeed:\nLS Filter: ${results[0]}\nLS Rocket: ${results[1]}\n` + return `FilterChecker Report for ${url}:\n\n${formatted}` + case ("palo" || "paloalto") : + results = await filters.palo(url) + formatted = `Palo Alto:\nRisk: ${results[2][1]}\nCategory: ${results[2][0].trim().replace(/^\s*$(?:\r\n?|\n)/gm,"")}\n` + return `FilterChecker Report for ${url}:\n\n${formatted}` + default: + set.status = 400 + return "Unknown filter. Accepted values: fortiguard, forti, lightspeed, ls, palo, paloalto" + } + } +}) +app.post("/check/:url/results.json",async ({ params,body,set })=>{ + let _:any = body + let bj = {"filter": "all"}; + try { + bj = JSON.parse(_) + } catch { + set.status = 400; + return {"error":"Bad JSON"} + } + + let url = params.url + if (bj.filter == "all") { + let url = params.url + let results = [await filters.fortiguard(url),await filters.lightspeed(url),await filters.palo(url)] + return {"fortiguard":results[0],"lightspeed":results[1],"paloalto":results[2]} + } else { + switch (bj.filter) { + case ("fortiguard" || "forti"): + return {"fortiguard":await filters.fortiguard(url)} + case ("lightspeed" || "ls"): + return {"lightspeed":await filters.lightspeed(url)} + case ("palo" || "paloalto") : + return {"palo":await filters.palo(url)} + default: + set.status = 400 + return {"error":"Unknown filter. Accepted values: fortiguard, forti, lightspeed, ls, palo, paloalto"} + } + } +}) + +let port = 10000; +if (process.env.PORT) {port = Number(process.env.PORT)} +if (!isNaN(Number(process.argv[process.argv.length - 1]))) {port = Number(process.argv[process.argv.length - 1])} +console.log(`Listening on port: ${port}`) +app.listen(port) \ No newline at end of file diff --git a/testing/autocheck.ts b/testing/autocheck.ts new file mode 100644 index 0000000..017c9f9 --- /dev/null +++ b/testing/autocheck.ts @@ -0,0 +1,13 @@ +import { stdin } from "bun"; +import filters from "../src/modules/filters.ts"; +let inp:any = await stdin.text() +inp = inp.split("\n") +const re = new RegExp("(?:https?://)?([^/]+)"); + +for (let i = 0; i < (inp.length - 1); i++) { + // @ts-ignore + let url = re.exec(inp[i])[1]; + let results = [await filters.fortiguard(url),await filters.lightspeed(url),await filters.palo(url)] + results[2] = [results[2][0].replaceAll(" ","").replaceAll("\n",""),results[2][1]] + console.log(`\n${url}:\n lightspeed: ${results[1]}\n forti: ${results[0]}\n palo: ${results[2]}`) +} \ No newline at end of file diff --git a/testing/rdapchecker.ts b/testing/rdapchecker.ts new file mode 100644 index 0000000..8bbea72 --- /dev/null +++ b/testing/rdapchecker.ts @@ -0,0 +1,2 @@ +import { getRDAP } from "../src/modules/whois"; +console.log(await getRDAP("172.233.190.246")) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2ad6233 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}