Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom JavaScript validation for HTTP(s) JSON responses #1573

Open
gorkem-bwl opened this issue Jan 16, 2025 · 12 comments
Open

Custom JavaScript validation for HTTP(s) JSON responses #1573

gorkem-bwl opened this issue Jan 16, 2025 · 12 comments
Labels
enhancement New feature or request
Milestone

Comments

@gorkem-bwl
Copy link
Contributor

Some services require more complex checks of the response than a simple KEYWORD or REGEX to perform the validation "Status UP" or "Status DOWN". To accommodate this, it would be highly beneficial to allow custom JavaScript code to be executed against a parsed JSON object from an HTTP(s) response.

The parsed JSON object could be accessible from the custom JavaScript code as a variable named msg.

The custom JavaScript code would be required to return:

  • Eithertrue or false for binary validation results.
  • or an array for more precise or detailed validation results.

Solution

Create a new monitor type: "HTTP(s) JSON Custom Function", derived from the existing "HTTP(s) - Keyword" monitor type.

In the UI:

  • Add a new text zone where users can write custom JavaScript code to validate the response.
  • Provide clear instructions and examples to guide users on writing valid code.

Example usage

  1. The HTTP(s) response body is parsed into a JSON object.

  2. The JSON object is passed to the custom JavaScript function, accessible as msg.

  3. Example:

    // Check if all users in the response are active
    return msg.users.every(user => user.isActive);
  4. The result (true, false, or an array) determines the status of the monitor.

This allows users to implement advanced validation logic that cannot be expressed using simple keywords or regular expressions, and increases flexibility and use cases for the monitoring tool.

Potential Challenges

  • Ensuring the security of executing user-provided JavaScript code.
  • Implementing proper error handling and logging for invalid or malicious scripts.

Additional Notes

  • Consider running the JavaScript code in a secure sandboxed environment to mitigate potential security risks.
  • Provide example templates for common use cases in the UI to simplify adoption.
@gorkem-bwl gorkem-bwl added the enhancement New feature or request label Jan 16, 2025
@gorkem-bwl gorkem-bwl added this to the 3.0 milestone Jan 16, 2025
@jasneetsingh6114
Copy link
Contributor

Hey @gorkem-bwl I would love to take up this issue

@gorkem-bwl
Copy link
Contributor Author

Sure. Could you please arrange a time with me here to discuss on the details of this issue? It's a big one so I wanted to make sure we're on the same page.

https://tidycal.com/bluewavelabs/general

You can have some sort of research (eg what to code/how to design the UI), so we can deep dive about talking about the implementation. Feel free to check other similar products.

@gorkem-bwl
Copy link
Contributor Author

Wanted to check back here @jasneetsingh6114

@YinDongFang
Copy link
Contributor

May I take up this if it's still open?

About the main challenges: Ensuring the security of executing user-provided JavaScript code. I think maybe we can use isolated-vm?

@gorkem-bwl
Copy link
Contributor Author

@YinDongFang sure, go ahead! Can you please write a list of todos on the frontend and backend?

Don't think about the frontend for now - when you are done with your analysis, I'll prepare a design for you so you can use it.

@YinDongFang
Copy link
Contributor

DB schema

  • add a enum value of type
  • add a string property to store the user's script

Server side

  • implement a function to securely execute user's script
  • implement a the getStatus function of new monitor type in NetworkService
    • validate HTTP response data (whether it is JSON)
    • pass the res as context to the function
    • validate the result (whether it is boolean)
    • error handling and logging
    • timeout handling

Client side

  • create a script editor component (maybe use monaco-editor)
    • support code suggestions and syntax validation
    • support test scripts with mock data
  • add a new monitor type option and show the code editor while the option selected (create and modify page)
  • display messages in the Incidents page (unexpected http response, runtime error, false result, timeout...)

This is my basic idea. Please let me know if I missed anything.

@gorkem-bwl
Copy link
Contributor Author

Looks good so far.

3 questions that popped up on my mind:

  1. What if the result is not json? Some of the services provide other formats - do you think we can make this generic so that the js code runs against it, and come up with a decision whether the service is up or not? If it will make things complicated, you can skip (1).

  2. Is it possible to send GET query that includes a json so that the server responds based on the json input?

  3. Is it possible to use lightweight editor? Monaco seems to be roughly 1Mb in size, and it looks like an overkill to me. I think either Prism.js or Highlight.js is the best bet here since the admin doesn't need a full blown editor. Code suggestions/syntax validation shouldn't be our problem IMHO. This can all be done outside of Checkmate in another IDE (eg VSCode).

For 2 I think we can always do that after we are done with the basics, but just wanted to write here to discuss.

@YinDongFang
Copy link
Contributor

  1. If considering other formats, we could pass the full response to user's code and let user determine the up/down status, but that would add complexity to the usage. I think we should start by handling the basic JSON format first, and think about other formats later.

  2. If support GET method, should we also support POST? And allow custom request headers? I think this also requires further discussion.

  3. I agree with you. I will do more research because I haven't used Prism.js or Highlight.js.

@gorkem-bwl
Copy link
Contributor Author

  • For 1, I am good.
  • For 2, yes. It's up to you to build both at the same time, or one after another. For the sake of simplicity, you may want to start GET and then we discuss about POST.
  • For 3, I am ok. I think we only have Prism.js as the option here as Highlight.js doesn't have editor capabilities.

@jasneetsingh6114
Copy link
Contributor

Hey @gorkem-bwl,

I apologize for the delay in getting back to you—I've been caught up with some college commitments.

Regarding our previous discussion, I scheduled a meeting for tomorrow, January 24th, 2025, on the very same day you mentioned that we should arrange one. However, since the issue has already been assigned to someone else, please let me know if I should cancel tomorrow’s meeting.

Thanks for your understanding!

@gorkem-bwl
Copy link
Contributor Author

gorkem-bwl commented Jan 23, 2025

@jasneetsingh6114 yes, let's cancel for now. You may want to check around for more issues - I'm pretty sure you can grab one. Please be on the lookout, join our Discord channel (link is in the readme.md file of the project) and do not hesitate to DM me and say hi :)

It was my bad that I didn't realize it was you. There are several meetings on and off. Sorry that I didn't catch it earlier. It's me, not you.

@YinDongFang
Copy link
Contributor

YinDongFang commented Feb 6, 2025

@gorkem-bwl @ajhollid Because of security problem of executing user code, I adopted an alternative approach to implement JSON validation. I referenced Uptime Kuma and Uptime, import jmespath for validation. Additionally, the solution supports different matching methods (regex, include, equal). Even if the response is not JSON but plain text, these three methods can still be used for additional validation.
#1700

About jmespath: https://jmespath.org/tutorial.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants
@YinDongFang @jasneetsingh6114 @gorkem-bwl and others