NFo control panel node.js library

This is used for general discussion that is not necessarily server-related.
Naleksuh
This is my homepage
This is my homepage
Posts: 298
https://www.youtube.com/channel/UC40BgXanDqOYoVCYFDSTfHA
Joined: Thu Jul 25, 2019 12:35 am

NFo control panel node.js library

Post by Naleksuh »

It is a very common request to have an API for the control panel. Thus far it has not actually happened. But I decided to make one myself and am currently working on creating a Node.js library for interacting with NFo's control panel. You can check it out on GitHub (trying to get this added to NPM, not sure how).


Currently the available methods are:

Code: Select all

NFO_ShutDownVDS(<email>, <password>, <servicename>);

Code: Select all

NFO_RestartVDS(<email>, <password>, <servicename>);

Code: Select all

NFO_ReinstallVDS(<email>, <password>, <servicename>, <newos>);

Code: Select all

NFO_ChangeVNCPassword(<email>, <password>, <servicename>);
So for example:

Code: Select all

NFO_ReinstallVDS("support@nfoservers.com", "hunter2", "hosted31", "Windows_Server_2019");
I plan to add more features in the future but this is the first library I have ever made so not entirely sure what I am doing yet.

Let me know if this works for you guys and if people find it useful I can keep working on it.
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

Awesome implementation :D

I'm not familar (well, hesitancy to learn) NodeJS so I hope you don't mind but I ported your API to C#.

If anyone wants a C# version (albeit untested) of Naleksuh API, checkout https://gist.github.com/Vortire/5583ff0 ... 71c833ba5c
Naleksuh
This is my homepage
This is my homepage
Posts: 298
Joined: Thu Jul 25, 2019 12:35 am

Re: NFo control panel node.js library

Post by Naleksuh »

Oh wow, your version is great. I personally was going to wait until I had more functions before putting it into other languages but it's good other people have interest already. I wonder if anyone will find our libraries to be of use?
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

I hope they will. I certainly will be using

Code: Select all

NFOHGET_GetCurrentEvents
to gather events from my NFOServers service so if nothing else coding the C# version of the API will help me and others automate certain procedures.

I do wish NFO would implement hashing though. It is not hard to hash a password and would allow API users to pass a hashed version of their password (more secure) rather than the plaintext equivalent. If NFO staff are reading this, all you'd have to do is add a simple SHA256 function somewhere in your work and just implement that function whenever you check against a password. Even if your database does not contain hashed passwords, just check against the hashed version of the database plaintext password instead. Then if you ever needed to compare plaintext passwords, you still have the database but all frontend interactions would be cryptographically more secure.
Naleksuh
This is my homepage
This is my homepage
Posts: 298
Joined: Thu Jul 25, 2019 12:35 am

Re: NFo control panel node.js library

Post by Naleksuh »

I am planning on working on adding new methods involving game servers, web servers, and voice servers, not just VDS.

Vortire if you are still active here, are you still interested in the C# version and have you had anyone use it thus far? I might be interested in adding new methods to it.
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

Indeed I am still active, I come here from time to time.

I've used the GET methods to create a system that automatically notifies me if my service is experiencing any attacks (thanks to Cloudflare I haven't had any in months). As if anyone else has used it, I'm unsure.

My service is usually setup-and-ignore so I haven't had to use any of the POST API methods yet.

If you want to add new methods, be my guest :)
User avatar
hiimcody1
Staff
Staff
Posts: 1593
Joined: Wed Dec 28, 2011 4:59 pm

Re: NFo control panel node.js library

Post by hiimcody1 »

One suggestion I'd have for the node one is to perhaps make it a class instead so you could pull some of your duplicated arguments out of the functions and into a constructor. That may just be my Java background showing though. :oops:
Naleksuh
This is my homepage
This is my homepage
Posts: 298
Joined: Thu Jul 25, 2019 12:35 am

Re: NFo control panel node.js library

Post by Naleksuh »

hiimcody1 wrote: Sat Aug 07, 2021 10:30 am One suggestion I'd have for the node one is to perhaps make it a class instead so you could pull some of your duplicated arguments out of the functions and into a constructor. That may just be my Java background showing though. :oops:
Hmm, which are you saying are the "duplicated arguments"? If you mean the email and password, this is because while most APIs requires a login step, NFOservers.com does not due to transmitting the password directly (this practice was questioned in viewtopic.php?t=15937 but it helps when making a library) - in most libraries you have to do a login step first then hold onto that, but with NFoservers.com it's a lot easier to use because you can do just about any action you want in a single request, by transmitting the username and password, which is why it's set up like that. It might however, make sense to have objects for holding onto specific services, which would probably also include the authentication needed to use them.

If that's not what you were talking about, what other ones are there?
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

Ah the joys of Node aha. The exact reason I refrain from it :oops:

Also Cody please could you push for hashed passwords, please :(
I know all connections are SSL and cryptographically secure but theres just something about seeing a plaintext password in a cookie that unsettles me.
User avatar
hiimcody1
Staff
Staff
Posts: 1593
Joined: Wed Dec 28, 2011 4:59 pm

Re: NFo control panel node.js library

Post by hiimcody1 »

Naleksuh wrote: Sat Aug 07, 2021 10:44 am Hmm, which are you saying are the "duplicated arguments"? If you mean the email and password, this is because while most APIs requires a login step, NFOservers.com does not due to transmitting the password directly (this practice was questioned in viewtopic.php?t=15937 but it helps when making a library) - in most libraries you have to do a login step first then hold onto that, but with NFoservers.com it's a lot easier to use because you can do just about any action you want in a single request, by transmitting the username and password, which is why it's set up like that. It might however, make sense to have objects for holding onto specific services, which would probably also include the authentication needed to use them.

If that's not what you were talking about, what other ones are there?
Sorry for the confusion here. I'm referring to those in this case and am indeed aware of how our internal systems work in regards to the username/password utilization. I wrote something similar to this years ago, once in PHP, once in Java, then a third time in node for some staff tools we use.

What I am saying is that you could break them out into vars inside a class object. It would just reduce the number of arguments to the functions in this case, which can sometimes lead to cleaner code. Perhaps I should have included an example initially.

I will show a version of your code converted to a class to illustrate what I'm talking about, hopefully this makes what I was saying more clear. I also added some generics to it just for example purposes.

Code: Select all

const fetch = require('node-fetch');

class NFO {
    constructor(email,password,service,servicetype) {
        this.email = email;
        this.password = password;
        this.service = service;
        this.servicetype = servicetype;
    }

    ChangeServiceAndType(service,servicetype) {
        this.service = service;
        this.serviceType = serviceType;
    }

    POST(controlpage, posttype) {
        fetch("https://www.nfoservers.com/control/" + controlpage, {
    		"headers": {
        		"Content-Type": "application/x-www-form-urlencoded",
        		"Cookie": "email=" + this.email + ";password=" + this.password + ";cookietoken=a"
    		},
		"body": "cookietoken=a&name=" + this.service + "&typeofserver=" + this.servicetype + "&" + posttype,
		"method": "POST"
	}).then(console.log);
    }

    Restart() {
        switch(this.servicetype) {
            case "game":
                this.RestartGame(this.service);
                break;
            case "virtual":
                this.RestartVDS(this.service);
        }
    }

    Stop() {
        switch(this.servicetype) {
            case "game":
                this.StopGame(this.service);
            case "virtual":
                this.SoftShutDownVDS(this.service);
        }   
    }

    Start() {
        switch(this.servicetype) {
            case "game":
                this.StartGame(this.service);
                break;
            case "virtual":
                this.StartVDS(this.service);
        }
    }

    StartGame() {
        this.POST("control.pl", "do_it_submitted=1&selection=start");
    }

    StopGame() {
        this.POST("control.pl", "do_it_submitted=1&selection=stop");
    }

    RestartGame() {
        this.POST("control.pl", "do_it_submitted=1&selection=restart");
    }

    ShutDownVDS(){
        this.POST("virtcontrol.pl", "power=off");
    }

    SoftShutDownVDS(){
        this.POST("virtcontrol.pl", "power=softoff");
        
    }
    
    StartVDS(){
        this.POST("virtcontrol.pl", "power=on");
    }

    RestartVDS(){
        this.POST("virtcontrol.pl", "power=softoff_then_off_then_on");
    }
    
    ReinstallVDS(newos){
        this.POST("virtcontrol.pl", "install=" + newos + "&install_confirm=1");
    }
    
    ChangeVNCPassword(){
        this.POST("virtserveraccess.pl", "changevnc=Change+VNC+password");
    }
}

//Example using new class and generics
let myService = new NFO("email@example.com","password","myVDSIdentifier","virtual");
myService.Stop();
myService.ChangeServiceAndType("differentVDSIdentifier",virtual);
myService.Stop();
I am a big fan of generics and reducing passing variables around where possible, just to make it easier for someone trying to implement a class later, I also prefer not add a bunch of functions to the global namespace where possible, hence the NFO class.
Vortire wrote: Sat Aug 07, 2021 11:19 am Ah the joys of Node aha. The exact reason I refrain from it :oops:

Also Cody please could you push for hashed passwords, please :(
I know all connections are SSL and cryptographically secure but theres just something about seeing a plaintext password in a cookie that unsettles me.
Node isn't the worst, but I'd prefer stick with Java if I could. But I'm stubborn like that.

It is on the todo list, but as part of a significantly wider scope than this. The entire authentication system needs reworking to allow for us to do cool things, such as an official API.

I imagine both you and Naleksuh have been looking at ways to read from the panel and have already worked out the pain that will be involved there.
Naleksuh
This is my homepage
This is my homepage
Posts: 298
Joined: Thu Jul 25, 2019 12:35 am

Re: NFo control panel node.js library

Post by Naleksuh »

Interesting; thanks for the information and example.

I will probably add an NFOServers class which will contain an email and password (but probably not the ChangeServiceAndType, would likely just submit service as a parameter). My only concern is what happens if someone wants to use multiple emails and passwords, but that probably shouldn't come up considering the secondary user feature.

The NFOServers class is a good idea, and I probably should have done this initially. It'll also make it easier for people to use it from NPM with a single line of code.

Also, thanks for the information about game server requests. I don't have any standalone gameservers registered with NFo so it's good to know what to add. From my memory back when I used to own them, they have a lot of really specific features like a file editor and taking tracert's, so I will need to figure out what those request parameters are somehow.
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

Very interesting API design Cody and I will append my C# API to also include the option to use instances of the class instead of having to statically calling each function and pass said arguments. As per the hashing, I'm glad it's on the to-do list and the sound of an official API just made my ears tingle, that would be a very nice touch to an already amazing hosting experience with NFO.
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

Also for every port of the API we need to ensure we sanitise input and remove characters such as ";" that could allow user input to break the way that Cookies are parsed into seperate arguments.
User avatar
Vortire
A semi-regular
A semi-regular
Posts: 24
Joined: Sat Mar 21, 2020 3:32 am
Location: United Kingdom
Contact:

Re: NFo control panel node.js library

Post by Vortire »

After thinking of ways to increase the easability of my C# version, I've decided to create my own syntax and allow "profiles" and "instructions" to making POST and GET requests easier. The main syntax is already coded, I just have to add functionality to the API now.

An example of what the API will look like:

Code: Select all

// You can choose to have "->" or " -> " as your main parsing structure, this configuration tells the interpreter to parse via the latter.
{{spaced-seperators}}

// Creating an API profile
Create_Profile -> Named:test -> WithEmail:e@e.e -> WithUsername:example -> WithPassword:example -> WithServiceName:exampleservice

// Creating the instruction to shutdown a server
Create_Instruction -> Named:shutd -> WithData:&shutdown=true

// Requesting server shutdown
SendPost -> To:example.pl -> WithProfile:test -> -> WithInstruction:shutd

// Requesting server status and setting response to a variable
// string endresult = null;
SendGet -> To:example.pl -> WithProfile:test -> WithInstruction:%null% -> SetResultTo:endresult

Naleksuh
This is my homepage
This is my homepage
Posts: 298
Joined: Thu Jul 25, 2019 12:35 am

Re: NFo control panel node.js library

Post by Naleksuh »

I'm probably gonna add an NFO class and have people submit their username and password once which will be stored in memory, but keep the service name as a parameter
Post Reply