diff --git a/rust/WEB-SERVER.md b/rust/WEB-SERVER.md index 24c22a25d7..e3a989d76c 100644 --- a/rust/WEB-SERVER.md +++ b/rust/WEB-SERVER.md @@ -51,7 +51,7 @@ $ sudo ./target/debug/agama-web-server serve If it fails to compile, please check whether `clang-devel` and `pam-devel` are installed. -By default the server uses port 3000 and listens on all network interfaces. You +By default the server uses port 80 and listens on all network interfaces. You can use the `--address` option if you want to use a different port or a specific network interface: @@ -76,7 +76,7 @@ option for that. You can check whether the server is up and running by just performing a ping: ``` -$ curl http://localhost:3000/ping +$ curl http://localhost/ping ``` ### Authentication @@ -85,7 +85,7 @@ The web server uses a bearer token for HTTP authentication. You can get the toke password to the `/auth` endpoint. ``` -$ curl http://localhost:3000/api/auth \ +$ curl http://localhost/api/auth \ -H "Content-Type: application/json" \ -d '{"password": "your-password"}' {"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDg1MTA5MzB9.3HmKAC5u4H_FigMqEa9e74OFAq40UldjlaExrOGqE0U"}⏎ @@ -94,7 +94,7 @@ $ curl http://localhost:3000/api/auth \ Now you can access protected routes by including the token in the header: ``` -$ curl -X GET http://localhost:3000/protected \ +$ curl -X GET http://localhost/protected \ -H "Accept: application/json" \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDg1MTA5MzB9.3HmKAC5u4H_FigMqEa9e74OFAq40UldjlaExrOGqE0U" ``` @@ -116,7 +116,7 @@ $ cargo install websocat Now, you can use the following command to connect: ``` -$ websocat ws://localhost:3000/ws +$ websocat ws://localhost/ws -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDg1MTA5MzB9.3HmKAC5u4H_FigMqEa9e74OFAq40UldjlaExrOGqE0U" ``` diff --git a/rust/agama-cli/src/auth.rs b/rust/agama-cli/src/auth.rs index 0b669a0856..80823d96a6 100644 --- a/rust/agama-cli/src/auth.rs +++ b/rust/agama-cli/src/auth.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; const DEFAULT_JWT_FILE: &str = ".agama/agama-jwt"; const DEFAULT_AGAMA_TOKEN_FILE: &str = "/run/agama/token"; -const DEFAULT_AUTH_URL: &str = "http://localhost:3000/api/auth"; +const DEFAULT_AUTH_URL: &str = "http://localhost/api/auth"; const DEFAULT_FILE_MODE: u32 = 0o600; #[derive(Subcommand, Debug)] diff --git a/rust/agama-lib/src/network/client.rs b/rust/agama-lib/src/network/client.rs index 1f2131e227..2c0bc5b1dc 100644 --- a/rust/agama-lib/src/network/client.rs +++ b/rust/agama-lib/src/network/client.rs @@ -3,7 +3,7 @@ use crate::error::ServiceError; use reqwest::{Client, Response}; use serde_json; -const API_URL: &str = "http://localhost:3000/api/network"; +const API_URL: &str = "http://localhost/api/network"; /// HTTP/JSON client for the network service pub struct NetworkClient { diff --git a/rust/agama-server/src/agama-web-server.rs b/rust/agama-server/src/agama-web-server.rs index ab5d701306..117ec800fa 100644 --- a/rust/agama-server/src/agama-web-server.rs +++ b/rust/agama-server/src/agama-web-server.rs @@ -64,9 +64,9 @@ fn find_web_ui_dir() -> PathBuf { #[derive(Args, Debug)] struct ServeArgs { - // Address/port to listen on (":::3000" listens for both IPv6 and IPv4 + // Address/port to listen on (":::80" listens for both IPv6 and IPv4 // connections unless manually disabled in /proc/sys/net/ipv6/bindv6only) - #[arg(long, default_value = ":::3000", help = "Primary address to listen on")] + #[arg(long, default_value = ":::80", help = "Primary address to listen on")] address: String, #[arg( long, diff --git a/web/README.md b/web/README.md index 691c045eca..b08b951d3e 100644 --- a/web/README.md +++ b/web/README.md @@ -21,7 +21,7 @@ use this command: The extra `--open` option automatically opens the server page in your default web browser. In this case the server will use the `https://localhost:8080` URL -and expects a running `agama-web-server` at `https://localhost:3000`. +and expects a running `agama-web-server` at `https://localhost`. This can work also remotely, with a Agama instance running in a different machine (a virtual machine as well). In that case run @@ -41,11 +41,11 @@ Example of running from different machine: # backend machine # using ip of machine instead of localhost is important to be network accessible # second address is needed for SSL which is mandatory for remote access - agama-web-server serve --address :::3000 --address2 :::443 + agama-web-server serve --address :::80 --address2 :::443 # frontend machine # ESLINT=0 is useful to ignore linter problems during development - ESLINT=0 AGAMA_SERVER=https://10.100.1.1:3000 npm run server + ESLINT=0 AGAMA_SERVER=https://10.100.1.1 npm run server ``` ### Debugging Hints diff --git a/web/webpack.config.js b/web/webpack.config.js index 6f81a9f190..555fb6e13f 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -3,36 +3,36 @@ const path = require("path"); const Copy = require("copy-webpack-plugin"); const Extract = require("mini-css-extract-plugin"); -const TerserJSPlugin = require('terser-webpack-plugin'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); +const TerserJSPlugin = require("terser-webpack-plugin"); +const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin"); const CompressionPlugin = require("compression-webpack-plugin"); -const ESLintPlugin = require('eslint-webpack-plugin'); +const ESLintPlugin = require("eslint-webpack-plugin"); const CockpitPoPlugin = require("./src/lib/cockpit-po-plugin"); -const StylelintPlugin = require('stylelint-webpack-plugin'); -const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); -const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const webpack = require('webpack'); +const StylelintPlugin = require("stylelint-webpack-plugin"); +const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); +const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); +const webpack = require("webpack"); const po_handler = require("./src/lib/webpack-po-handler"); /* A standard nodejs and webpack pattern */ -const production = process.env.NODE_ENV === 'production'; +const production = process.env.NODE_ENV === "production"; const development = !production; /* development options for faster iteration */ -const eslint = process.env.ESLINT !== '0'; +const eslint = process.env.ESLINT !== "0"; /* Default to disable csslint for faster production builds */ -const stylelint = process.env.STYLELINT ? (process.env.STYLELINT !== '0') : development; +const stylelint = process.env.STYLELINT ? (process.env.STYLELINT !== "0") : development; // Agama API server. By default it connects to a local development server. -let agamaServer = process.env.AGAMA_SERVER || "localhost:3000"; +let agamaServer = process.env.AGAMA_SERVER || "localhost"; if (!agamaServer.startsWith("http")) { agamaServer = "http://" + agamaServer; } // Obtain package name from package.json -const packageJson = JSON.parse(fs.readFileSync('package.json')); +const packageJson = JSON.parse(fs.readFileSync("package.json")); // Non-JS files which are copied verbatim to dist/ const copy_files = [ @@ -56,32 +56,36 @@ const plugins = [ ].filter(Boolean); if (eslint) { - plugins.push(new ESLintPlugin({ extensions: ["js", "jsx"], failOnWarning: true, })); + plugins.push(new ESLintPlugin({ extensions: ["js", "jsx"], failOnWarning: true })); } if (stylelint) { - plugins.push(new StylelintPlugin({ - context: "src/", - })); + plugins.push( + new StylelintPlugin({ + context: "src/", + }), + ); } /* Only minimize when in production mode */ if (production) { - plugins.unshift(new CompressionPlugin({ - test: /\.(js|html|css)$/, - deleteOriginalAssets: false - })); + plugins.unshift( + new CompressionPlugin({ + test: /\.(js|html|css)$/, + deleteOriginalAssets: false, + }), + ); } module.exports = { - mode: production ? 'production' : 'development', + mode: production ? "production" : "development", resolve: { - modules: ["node_modules", path.resolve(__dirname, 'src/lib')], + modules: ["node_modules", path.resolve(__dirname, "src/lib")], plugins: [new TsconfigPathsPlugin({ extensions: [".js", ".jsx", ".json"] })], - extensions: ['', '.js', '.json', '.jsx'] + extensions: ["", ".js", ".json", ".jsx"], }, resolveLoader: { - modules: ["node_modules", path.resolve(__dirname, 'src/lib')], + modules: ["node_modules", path.resolve(__dirname, "src/lib")], }, watchOptions: { ignored: /node_modules/, @@ -106,13 +110,13 @@ module.exports = { context: ["/api"], target: agamaServer, secure: false, - } + }, ], // special handling for the "po.js" requests specially setupMiddlewares: (middlewares, devServer) => { devServer.app.get("/po.js", po_handler); return middlewares; - } + }, }, devtool: "source-map", stats: "errors-warnings", @@ -139,7 +143,7 @@ module.exports = { }), // remove also the spaces between the tags new HtmlMinimizerPlugin({ minimizerOptions: { conservativeCollapse: false } }), - new CssMinimizerPlugin() + new CssMinimizerPlugin(), ], }, @@ -152,58 +156,58 @@ module.exports = { { loader: "babel-loader", options: { - plugins: [development && require.resolve('react-refresh/babel')].filter(Boolean), + plugins: [development && require.resolve("react-refresh/babel")].filter(Boolean), }, - } - ] + }, + ], }, { test: /\.s?css$/, use: [ Extract.loader, { - loader: 'css-loader', + loader: "css-loader", options: { sourceMap: true, url: { // Only follow the Agama fonts links to be processed by the next rule and place // them in dist/fonts - filter: (url) => url.includes("./fonts/") - } - } + filter: (url) => url.includes("./fonts/"), + }, + }, }, { - loader: 'sass-loader', + loader: "sass-loader", options: { sourceMap: development, sassOptions: { includePaths: ["node_modules"], - outputStyle: production ? 'compressed' : undefined, + outputStyle: production ? "compressed" : undefined, }, }, }, - ] + ], }, { test: /\.(eot|ttf|woff|woff2)$/, - type: 'asset/resource', + type: "asset/resource", generator: { - filename: 'fonts/[name][ext]', - } + filename: "fonts/[name][ext]", + }, }, // Load SVG files { test: /\.svg$/i, - type: 'asset', - resourceQuery: { not: [/component/] } // exclude file import includes ""?component" + type: "asset", + resourceQuery: { not: [/component/] }, // exclude file import includes ""?component" }, { test: /\.svg$/i, issuer: /\.jsx?$/, resourceQuery: /component/, // *.svg?component - use: ['@svgr/webpack'] - } - ] + use: ["@svgr/webpack"], + }, + ], }, - plugins: plugins + plugins: plugins, };