milutinke / sqcp

Squad Control Panel (SQCP) is a simple Open-Source solution for administrating your Squad game server written in Node JS (Express) and Vue JS (Vuetify Framework), utilizing the RCON protocol and MySQL database.
MIT License
35 stars 16 forks source link

Support for SQCP with Nginx Proxy and HTTPS #8

Closed ghost closed 2 years ago

ghost commented 2 years ago

Hi, I think your work is remarkable and a great solution.

I'm trying to implement SQCP on a HTTPS-enabled website with Nginx. Currently, there are some CSS and JS resources 404 when using nginx proxy pass to redirect traffic to a path (i.e. example.com/sqcp -> proxy_pass localhost:3000). I suppose this has do to with the fact that SQCP JS is handling requests on the "/" path and not "/sqcp" path. Could you please give me some pointers on how I should modify the code to allow SQCP responding to "example.com/sqcp"? Any help is highly appreciated!

BTW, here are some features which I think might be helpful.

  1. Showing current map and next map on the dashboard.
  2. Creating a new view for changing map + setting next map with a list of all map layers.
  3. Implementing a duration (expiration) system for server admins similar to how banned players durations work. (Helpful for giving out non-permanent reserve slots for players positively contributing to the server game env, etc.)
milutinke commented 2 years ago

Hi, I think your work is remarkable and a great solution.

I'm trying to implement SQCP on a HTTPS-enabled website with Nginx. Currently, there are some CSS and JS resources 404 when using nginx proxy pass to redirect traffic to a path (i.e. example.com/sqcp -> proxy_pass localhost:3000). I suppose this has do to with the fact that SQCP JS is handling requests on the "/" path and not "/sqcp" path. Could you please give me some pointers on how I should modify the code to allow SQCP responding to "example.com/sqcp"? Any help is highly appreciated!

BTW, here are some features which I think might be helpful.

1. Showing current map and next map on the dashboard.

2. Creating a new view for changing map + setting next map with a list of all map layers.

3. Implementing a duration (expiration) system for server admins similar to how banned players durations work. (Helpful for giving out non-permanent reserve slots for players positively contributing to the server game env, etc.)

You need to change this part of the code on the back-end: https://github.com/milutinke/sqcp/blob/master/backend/App.js

So basically change it to this:

    // Static files
    this.express.use('/sqcp/js', Express.static(Path.join(__dirname, '/dist/js')));
    this.express.use('/sqcp/css', Express.static(Path.join(__dirname, '/dist/css')));
    this.express.use('/sqcp', Express.static(Path.join(__dirname, '/dist')));

    this.express.use(History());

    // Double (fixes bug with connect-history-api-fallback)
    this.express.use('/sqcp/js', Express.static(Path.join(__dirname, '/dist/js')));
    this.express.use('/sqcp/css', Express.static(Path.join(__dirname, '/dist/css')));
    this.express.use('/sqcp', Express.static(Path.join(__dirname, '/dist')));

That should do it.

As for the current map, I can't do it over RCON I think, I'd need to include some game querying library, but it should be easy to add. I actually have the map choosing panel somewhere it's half finished, I'll find it when I have some time and add it, if I remember correctly the only reason I did not add it because it was kinda slow when loading. As for the admin expiration, I'll include that in the new version of the panel.

ghost commented 2 years ago

Hi milutinke, thanks a lot for the feedback! I made the suggested modifications. The app is now listening on localhost/sqcp. However, the CSS and JS resources are still 404 when accessing the site. It seems the Express is still trying to collect resources from the base URL, even though these resources are available on localhost/sqcp/css... instead of localhost/css...

image

I haven't had time to dig in, but I suppose I need to make further changes on how Express is serving the CSS and JS resources, not just the path it's listening on. If you have further suggestions or some tips on what I should lookout for, I would greatly appreciate it.

Lastly, regarding this topic

As for the current map, I can't do it over RCON I think, I'd need to include some game querying library, but it should be easy to add.

The Rcon command for showing current map is ShowCurrentMap and the command for the next map is ShowNextMap. You could try it out by implementing the standard Source RCON library. Please let me know your thoughts.

ghost commented 2 years ago

Hi milutinke, after some experimentation, I produced a make-shift solution to address this issue. There were many changes required to SQCP coding in addition to changing the express path that you mentioned.

  1. Changing the /frontend/squad-control-panel/dist/index.html file produced by yarn build. (I'm still trying to figure out how to implement the change during the build process). By manually changing the link references, the webpage can collect resources normally now. https://github.com/milutinke/sqcp/blob/master/docs/setup.md
  1. Once the installation is complete, run: yarn build
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="icon" href="/sqcp/favicon.ico">
    <title>squad-control-panel</title>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
    <link href="/sqcp/css/app.9e1a8384.css" rel="preload" as="style">
    <link href="/sqcp/css/chunk-vendors.42e53ce6.css" rel="preload" as="style">
    <link href="/sqcp/js/app.5f5dd984.js" rel="preload" as="script">
    <link href="/sqcp/js/chunk-vendors.2888e29d.js" rel="preload" as="script">
    <link href="/sqcp/css/chunk-vendors.42e53ce6.css" rel="stylesheet">
    <link href="/sqcp/css/app.9e1a8384.css" rel="stylesheet">
  </head>
  <body>
    <noscript>
      <strong>We're sorry but squad-control-panel doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <script src="/sqcp/js/chunk-vendors.2888e29d.js"></script>
    <script src="/sqcp/js/app.5f5dd984.js"></script>
  </body>
</html>
  1. Changing the paths of different views in frontend/squad-control-panel/src/router/index.js https://github.com/milutinke/sqcp/blob/master/frontend/squad-control-panel/src/router/index.js
  // Example of modified path for Online Players
  {
    path: '/sqcp/online-players',
    name: 'Online Players',
    component: OnlinePlayers,
    meta: {
      menu: {
        icon: 'mdi-account-multiple',
      },
      authMiddelware: true,
    },
  },
  1. Create another server block on Nginx for http://localhost:3000/api/v1 so that the server bans and admins text can be redirected accordingly.

In the end, the web app is functioning properly with nginx proxy and HTTPS. Please feel free to close this issue if you don't have any other comments the add.

milutinke commented 2 years ago

I forgot to mention, that you have to change the link on the frontend too: https://github.com/milutinke/sqcp/blob/e645731eeaa7e2e4e04406abed101c78a531f60d/frontend/squad-control-panel/src/main.js#L17

As for the resources, I think it could be done by Babel, but I am not familiar with the front end stuff at all, I am a backend dev, so for now changing them after the compilation is doing the job.

For routes in Vue, you can do nested routes, instead of typing /sqcp for each single route you can have a root one and have it have other ones as children: https://router.vuejs.org/guide/essentials/nested-routes.html

An example:

const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        // UserProfile will be rendered inside User's <router-view>
        // when /user/:id/profile is matched
        path: 'profile',
        component: UserProfile,
      },
      {
        // UserPosts will be rendered inside User's <router-view>
        // when /user/:id/posts is matched
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

As for the RCON, my plan is to port over the SQCP to use Squad JS, since that will enable some features like real time feeds, so I do not need to have all of that logic written again from scratch, and RCON will be more stable with that.

milutinke commented 2 years ago

Oh, I already have implemented the next and current maps, but I haven't used them lmao, there is even a route for it: /api/v1/rcon/layer Could you maybe give me a RCON info for a test server if you have it, so I could test it out, I do not have a server currently?

ghost commented 2 years ago

Hi, please find me on discord Typhorus#6059 regarding your requests. I will close this issue for now.