Documentation for irc-hybrid-client
Login Config
Select configuration method

There are two possible methods that may be used to define the web server configuration settings. The settings may be stored as properties in the "credentials.json" file, or the settings may be defined as environment variables with use of .env file supported. Only one method can be used at a time. If the credentials.json file exists, it will be parsed for settings, otherwise the environment variables will be parsed for settings.

On a multi-user system, you may want to change permissions on the config file to protect credentials.

The introduction of two concurrent configuration schemes may introduce some security questions. Configuration of security related properties could contain ambiguous conflicting values between the two configuration methods. To minimize risk of ambiguous configuration, only one method is used at one time. In the case where the file "credentials.json" exists then configuration will be parsed from the credentials.json file and the environment variable configuration will be ignored. In case case where the file "credentials.json" does not exist then the configuration will be parsed from UNIX environment variables. For configuration properties that have not been defined, the server/config/index.mjs module will define fallback default values. In a future release, the credentials.json config file may be deprecated (breaking change) to standardize all of the server configuration with environment variables or the .env file.

The configuration examples on this page will include both configuration methods, credentials.json method first and environment variable method second, each with a slightly different background color.

  credentials.json method - Examples with this background color
  environment variable method - Examples with this background color
NODE_ENV environment variable

Do not include the NODE_ENV environment variable in the .env file. It is used by the NPM package manager and used internally by node itself. Defining NODE_ENV in the .env file will generate a configuration validation error. The NODE_ENV variable should be defined external to the program to a value of "development" or "production" as described in the node documentation.

Default Values

When configuration settings are omitted from the configuration, each setting will fall back to a default value defined in the server/config/index.mjs file. In order to reduce the size and complexity of the configuration, setting that remain at the default values may be omitted from both credentials.json and environment variables.

Bare minimum settings for testing

Ok... Let's say that you just want to clone irc-hybrid-client into a virtual machine and try it on a private network. What is the minimum configuration needed?

Most of the configuration settings can be allowed to fall back to the configuration defaults. At minimum, the web server configuration needs:

Create configuration settings

Option 1 of 4 - To make a minimal configuration that uses the credentials.json configuration method, copy the following JSON object, then paste it into a new credentials.json file in the base folder of the repository. Protect file permissions using "chmod 600 credentials.json".

{
  "configVersion": 2,
  "loginUsers": [
    {
      "userid": 1,
      "user": "user1",
      "name": "Bob Smith",
      "hash": "---BCRYPT-HASH-GOES-HERE---"
    }
  ],
  "serverTlsKey": "/home/user1/tls/privkey.pem",
  "serverTlsCert": "/home/user1/tls/fullchain.pem",
  "tls": true,
  "port": 3003,
  "cookieSecret": "---COOKIE-SECRET-GOES-HERE---"
}

Option 2 of 4 - To make a minimal configuration that uses environment variables, copy the following environment variables, then paste them into a .env file in the base folder of the repository. Protect file permissions using "chmod 600 .env". To use environment variables as the configuration, make sure the credentials.json file does not exist in the base folder of the repository.

ENV_VAR_CONFIG_VERSION=2
LOGIN_USER_USERID=1
LOGIN_USER_USER="user1"
LOGIN_USER_NAME="Bob Smith"
LOGIN_USER_HASH="---BCRYPT-HASH-GOES-HERE---"
SERVER_TLS_KEY=/home/user/tls/privkey.pem
SERVER_TLS_CERT=/home/user/tls/fullchain.pem
SERVER_TLS=true
SERVER_PORT=3003
SESSION_SECRET="---COOKIE-SECRET-GOES-HERE---"

Option 3 of 4 - To create a new credentials.json file using a full configuration template, the git repository includes an example configuration file template named "example-credentials.json". Create a new credentials.json file as follows:

  cp -v example-credentials.json credentials.json
  chmod 600 credentials.json

Option 4 of 4 - To create an environment variable .env file using a full configuration template. the git repository includes an example environment variable template named "example-.env". To use environment variables as the configuration, make sure the credentials.json file does not exist in the base folder of the repository. Create a new .env file as follows:

  cp -v example-.env .env
  chmod 600 .env
Configuration File version

This is intended for future use. It provides a method to issue a startup message when attempting to use a configuration file that may be impacted by breaking changes. It will remain at 2 until there is a breaking change.

This was increased from 1 to 2 when the password hash function was upgraded to bcrypt in Version 0.1.0 as a breaking change.

{
  "configVersion": 2,
}
ENV_VAR_CONFIG_VERSION=2
Certificates

Next, 3 lines are used to specify the path and filenames for TLS certificates. Certificates are discussed in more detail in the installation section.

Since it is recommended to run this program in a non-privileged account, it may be necessary to make a copy of the certificate files in a local folder where the web server will have read access. It is NOT recommended to run the IRC client as root, simply for certificate access.

The path location would depend on your specific Linux system. To configure the web server to listen for HTTPS encrypted connections, this section would look something like this:

{
  "serverTlsKey": "/home/user1/tls/privkey.pem",
  "serverTlsCert": "/home/user1/tls/fullchain.pem",
  "tls": true,
}
SERVER_TLS_KEY=/home/user/tls/privkey.pem
SERVER_TLS_CERT=/home/user/tls/fullchain.pem
SERVER_TLS=true

If on the other hand you are using the program in a development environment without TLS certificates, or you are using an external load balancer or proxy that provides TLS capabilities, set these lines as follows to disable TLS. The lines containing empty filenames may be omitted from the configuration.

{
  "serverTlsKey": "",
  "serverTlsCert": "",
  "tls": false,
}
# SERVER_TLS_KEY=
# SERVER_TLS_CERT=
SERVER_TLS=false
Listen Port

Set the web server listen port to the desired port number for the web server. For security reasons, this program should be run as a non-privileged user using a non-privileged ports 1024 or greater.

If you prefer to use restricted port 443 for your webserver, it would be recommended to place the IRC client on an alternate non-privileged port, then use iptables or nftables firewall rules to exchange port numbers to 443 as packets cross the firewall.

{
  "port": 3003,
}
SERVER_PORT=3003
Session Credentials

The cookie secret is used to place digital signatures on session cookies. These cookies are used to authorize http web requests. The value shown here is only an example, and you should generate your own unique randomly generated string of characters.

The expire time represents the time in seconds after which the session credentials will expire. A value of 86400 seconds will set the login expiration at 24 hours, or once per day. Based on the ease of use of browser password managers, 24 hours has worked out to a convenient duration. If a rolling cookie is enabled, the expiration date of the cookie is reset each time the page is loaded.

If your session expires in the middle of a conversation, a user login page will load. The backend web server will maintain a cache of messages that occur while disconnected. You should be able to continue your conversation after re-authenticating without any indication to people in the conversation.

The configuration property "instanceNumber" is used for the case where multiple instances are running, using the same host name, but using different port numbers. In the case where a web browser is connected simultaneously to two server instances with same host name and the same cookie name, login of one session would likely disconnect the other session due to replacement of the browser session cookie of the same cookie name. The instanceNumber property is used to make the cookie name unique. The instanceNumber should be an integer between 0 and 65535. The instanceNumber should be unique for each instance running on a web server.

When running multiple servers, one suggested option would be to optinally set the instance number to the same value as the port number. This makes the cookies easy to identify.

Security Caution:

A web browser does not consider the server port number when selecting session cookies for HTTP server requests. Running multiple instances of irc-hybrid-client with the same host name, but different server port numbers, can result in the browser submitting multiple session cookies to the web server. Although the instanceNumber configuration property is intended to implement unique cookie names for each instance (port number), unique cookie names WILL NOT prevent the browser from submitting multiple cookies for all sessions that matches the host name. Therefore, it is not recommended to run multiple instances of irc-hybrid client on the same host name unless you understand the security implications associated with cookies and concurrent sessions. This caution does not apply to different users who are connecting from different browser/computer. It does apply to multiple tabs in a one web browser. This setup may be useful for one single user to use multiple browser tabs for simultaneous connection to different IRC networks.

{
  "cookieSecret": "Lg9HLgCEmtag4Ff7",
  "sessionExpireAfterSec": 604800,
  "instanceNumber": 3003,
}
SESSION_SECRET="Lg9HLgCEmtag4Ff7"
SESSION_EXPIRE_SEC=604800
SERVER_INSTANCE_NUMBER=3003
Assign Login Password

In the current version of the program, the username and password that you will use to gain access to the web page must be configured using the ssh terminal during the initial configuration of the web server. There is no provision to change the password from within the web page.

As written, this program was intended to be a single user, private web server. This will limit to password database to 1 authorized user. This user would be the owner of the private web server. Therefore, there was no reason to unnecessarily increase security risk by adding an API capable of writing password credentials. Should someone gain unauthorized access, such as a forged cookie or cross-site script, it would not be possible to remotely modify the password file, or any of the server configuration. Should the account password become compromised, the web interface allows remote shutdown of the server. This would protect it until a new password were set using the ssh terminal.

Case 1 - Configuration using credentials.json

A brief note about syntax. The credentials.json file represents a JSON structured data object. JSON syntax must be exact, with matching curly braces and proper use of commas. The credentials.json file includes a loginUsers property. The square brackets [ ] define a javascript array. Each of the curly braces { } within the array is a javascript object used to define an individual user. The user object contains 4 properties listed as key/value pairs. Note the use of double quotes and commas between key/value pairs except the last has no comma. In fact, there is only 1 user. Only the first array object at index 0 (userid 1) is relevant.

A small javascript program has been included to create a user password hash and automatically update the credentials.json file. The program can be executed from the command line to assign the username and password for the primary user at array index 0, (userid 1). To run this program, change directory to the tools folder, and execute the updateAuthForUser_1.mjs program as in the following example.

cd tools
node updateAuthForUser_1.mjs

This will start an interactive session in the command line terminal. In this example, the "user" was set to user1. The "name" was set to Bob Smith. In this example, the password was set to zuwa79xoJxLJ, but you should select your own random password. A bcrypt function was used to generate a salted hash. The data was written to the credentials.json file, and an excerpt from the credentials.json was displayed for your review.

$ node updateAuthForUser_1.mjs 

Caution, you are editing the password file.

This will set a new login user/password for userid=1 at array index=0.
This is a static password not editable online.
It is intended there is only one user for the program.
This must be run from the tools/ folder to find credentials.json.

User up to 16 characters a-z,A-Z,0-9
Enter new user:user1

Name up to 32 characters a-z,A-Z,0-9 and spaces
Enter new name (user1):Bob Smith

Enter new password:zuwa79xoJxLJ
{
  "loginUsers": [
    {
      "userid": 1,
      "user": "user1",
      "name": "Bob Smith",
      "hash": "$2a$10$eJDI3vQNIqblM4tBhCdwuumbpzRtsX6.AYApsaUfxa9CS.ztamKSC"
    }
  ]
}

Failed login attempts will increment a counter of failed attempts by IP address. The limit is set to allow 5 failed password attempts per hour for each IP address. Exceeding this limit will temporarily disable login for 1 hour. The may be reset at any time by shutdown and restart of the web server.

Privacy Caution: The web userid numeric value (userid: 1) and web login timestamp are saved in the web browsers's localStorage API. See: FAQ

Next, return from the tools folder to the repository folder.

cd ..

If you really feel you need to create a second username/password entry, such as one for your phone and one for your desktop, you can create one at index 0 using the above script, then copy/paste the entire javascript object as an additional javascript object in the array. Use care to maintain valid JSON format with commas and braces.

Case 2 - Configuration using environment variables

A small javascript program has been included to create a user password hash and generate environment variables that can be copy/paste into the .env file or other environment variable configuration. The program can be executed from the command line to assign the username and generate password hash for the primary user (userid 1). To run this program, change directory to the tools folder, and execute the genEnvVarAuthForUser_1.mjs program as in the following example.

  cd tools
  node genEnvVarAuthForUser_1.mjs

This will start an interactive session in the command line terminal. In this example, the "user" was set to user1. The "name" was set to Bob Smith. In this example, the password was set to zuwa79xoJxLJ, but you should select your own random password. A bcrypt function was used to generate a salted hash. The data was printed to the terminal so the environment variables can be copied in order to paste the values into an external environment variable configuration. If the .env file is used, all 4 lines can be copied to the .env file.

$ node genEnvVarAuthForUser_1.mjs 

You are running a script to generate user login environment variables.
This is a static password not editable online.
It is intended there is only one user for the program.
This must be run from the tools/ folder.


User up to 16 characters a-z,A-Z,0-9
Enter new user:user1

Name up to 32 characters a-z,A-Z,0-9 and spaces
Enter new name (user1):Bob Smith

Enter new password:zuwa79xoJxLJ

You may copy/paste these environment variables


LOGIN_USER_USERID=1
LOGIN_USER_USER="user1"
LOGIN_USER_NAME="Bob Smith"
LOGIN_USER_HASH="$2a$10$0pr9Q21L7CFoSw5.FjbW0.izOzQtBTqQjOGbZJabM2MMNdSxKyfpO"

Only 1 user account can be defined when using environment variables for configuration. If you want to add a second login password, you will need to use the credentials.json or configure the program to use the remote login feature.

Failed login attempts will increment a counter of failed attempts by IP address. The limit is set to allow 5 failed password attempts per hour for each IP address. Exceeding this limit will temporarily disable login for 1 hour. The may be reset at any time by shutdown and restart of the web server.

Privacy Caution: The web userid numeric value (userid: 1) and web login timestamp are saved in the web browsers's localStorage API. See: FAQ

Next, return from the tools folder to the repository folder.

  cd ..
Session Store (Optional)

By default, irc-hybrid-client web server uses Memorystore as a RAM database to hold user's login session. Considering the application is a single user IRC client, memorystore should be adequate for most users. The memorystore includes a memory safe prune function to remove expired sessions preventing a memory leak. The disadvantage of RAM based storage is that when the web server is restarted, such as following a reboot, the current login state is lost. A user login password entry will be required after a server restart. If you are using a password manager, this is not a big deal.

If you prefer persistent session storage, the application supports Redis, which is a simple key/value store. It is assumed that redis is running on the same server as the irc-hybrid-client so a non-encrypted TCP connection would be safe. It is mandatory that the local firewall protect the redis TCP ports from external internet access. A redis password is not required to access redis locally behind a firewall. The redis prefix should be set to a unique value if more than one web server is using this instance of redis.

As a security note, generally session storage includes server side data needed to authorize HTTP web requests based on user login state. A Redis server installation is independent of the irc-hybrid-client instance. In the case of a multi-user system or cases where other users may have access to the Redis database contents, it is recommended to disable Redis and use Memorystore.

If you are not familiar with redis, it is recommended to use the default configuration to use Memorystore for session storage.

{
  "sessionEnableRedis": true,
  "sessionRedisPrefix": "irc001:",
  "sessionRedisPassword": "",
}
SESSION_ENABLE_REDIS=true
SESSION_REDIS_PREFIX="irc001:"
# SESSION_REDIS_PASSWORD=

There is a redis client `redis-cli` that can be used to view or clear the session store.

Security Contact

The security contact is optional. For all web servers, a standardized URL route may been defined which would include security contact information located in a flat text file at: "/.well-known/security.txt". Should a security issue be detected on your server by a third party, this provides a method to contact the server owner and notify them of the security issue. The email address should be prefixed with "mailto:". This URL is publicly readable without requiring login or session cookie. To enable this feature, set a valid security email address. The expiration date is typically 1 year out and must be entered using a standard UNIX date format.

A date string can be generated using the following bash command:

        date --date='1 year' --rfc-email
{
  "securityContact": "mailto:security@example.com",
  "securityExpires": "Fri, 1 Apr 2022 08:00:00 -0600",
}
SITE_SECURITY_CONTACT=mailto:security@example.com
SITE_SECURITY_EXPIRES="Fri, 1 Apr 2022 08:00:00 -0600"

To disable the security contact, modify these lines as follows:

{
  "securityContact": "",
  "securityExpires": "",
}
# SITE_SECURITY_CONTACT=
# SITE_SECURITY_EXPIRES=
PID file path

A valid file path may be defined to a folder capable of write access to the web server. When the server starts, the process id (PID) number is written to this file. This is intended for use by external scripts for purposes like restarting the application for various purposes such as restart after log file rotation.

Set the PID file path to an empty string to disable the PDF file.

{
  "pidFilename": "/home/user1/tmp/ircHybridClient.PID",
}
SERVER_PID_FILENAME=/home/user1/tmp/ircHybridClient.PID
Restart using PID file (Optional)

After making changes to the configuration in credentials.json or .env, it is necessary to stop and restart the irc-hybrid-client web server to load the new configuration.

Assuming a PID filename (previous section) has been configured and contains a full path name, a bash script "restart.sh" for credentials.json configuration or "restart2.sh" for environment variable configuration may be executed from the base folder of the repository to retrieve the PID number, kill previous irc-hybrid-client instance, and launch a new instance of the irc-hybrid-client web server.

The restart.sh script requires the Linux "jq" utility for parsing JSON content. The jq linux package may be installed using "apt-get install jq" in Debian or Ubuntu. The restart2.sh script used with enviornment variables does not require this package to be installed.

The restart2.sh script requires that the environment variable SERVER_PID_FILENAME be assigned and exported before running the script. The optional SERVER_INSTANCE_NUMBER variable will be used if found.

The .gitignore file includes "custom*" to allow creation of custom shell scripts. Since 2 environment variables are required for the restart2.sh script, it may be possible to create a script similar to the following. This is only a suggestion, please write your own script.


#!/bin/bash
#
# Determine irc-hybrid-client configuration method
# Call proper restart.sh or restart2.sh
#
if [ -f credentials.json ] ; then
echo "irc-hybrid-client config: credentials.json"
./restart.sh
else
echo "irc-hybrid-client config: .env"
export SERVER_INSTANCE_NUMBER=3
export SERVER_PID_FILENAME=/home/user/tmp/ircHybridClient003.PID
./restart2.sh
fi

The restart.sh or restart2.sh utility is intended to be run manually to assist with editing of credentials.json or .env. It is not intended to be run from cron.

Disable Server List Editor Web Page

The boolean property "disableServerListEditor" can be set to true to disable the web server API routes that are capable to write changes to the servers.json file. When disabled, API calls to /irc/serverlist with methods GET, POST, PATCH, COPY, and DELETE will return status 405 Method not allowed. This will disable the web page that is used to modify the list of available IRC server definitions.

When disabled, a user of the IRC client is still able to specify a unique nickname and real name prior to connect, but the values would not persist after the web server is restarted.

The capability to disable the interface can be useful to restrict access of the IRC client to one specific IRC network, or to control the list of available IRC channel preset buttons. Logging of raw IRC server messages may also be restricted.

In terms of security risk, when set to true to disable the interface, all configuration changes would require SSH shell access. No remote configuration changes would be possible from the web page.

When set to false the API routes will be active. HTTP requests will be capable to write changes to the servers.json file, but only within the restrictions of the input validation checks. Authorization to use the API requires user login and a valid session cookie.

{
  "disableServerListEditor": false,
}
IRC_DISABLE_LIST_EDITOR=false
Restore Message Cache After Web Server Restart

The web server includes optional code that can be used to save and reload a copy of the IRC message cache across web server restarts.

When enabled in the credentials.json file, Unix signals SIGINT and SIGTERM will cause the web server to asynchronously write the cache file, then exit with status 0. The JSON encoded cache includes timestamp, cache pointer, and message data converted to an array of type utf-8 String to file `logs/savedMessageCache.json`.

As the web server is restarted, it will asynchronously read the cache file. If the timestamp age is 300 seconds or less (5 minutes), the cache pointer and cache data is restored as Array of type Buffer. Cache data is then removed from the file.

There is one limitation to this feature. When changing servers using the Server List in the browser, changing servers to different groups numbers, or changing to a server in group 0 will clear the cache. Therefore, the selected server to have cache restored upon restarting the web server must be the first server in the list (the default server), or else in a group of servers of the same group number at the start of the list.

Regarding server reboot, if the distribution of Linux does not send a SIGINT or SIGTERM to the irc-hybrid-client process before shutdown, then the cache will not be written. Debian seems to send a SIGKILL different signal before shutdown. According to the NodeJs documentation "SIGKILL cannot have a listener installed, it will unconditionally terminate Node.js on all platforms.". Therefore to preserve the cache across server reboots, it may be necessary to issue a SIGINT or SIGTERM manually immediately before server shutdown for reboot. This could be scripted.

This feature may be used to write bash scripts to restart the web server. It is up to the user to write his own script, and this is only an example to get you started. Assuming the "pidFilename" was configured in the credentials.json file, the web server Unix process PID number will be saved in that file when the web server starts. A bash script can read the PID number from the file and send the kill signal to the web server's process.

IRC_HYBRID_CLIENT_PATH=$HOME/tmp/irc-hybrid-client.PID
PID_NUMBER=$(cat $IRC_HYBRID_CLIENT_PATH)
if [ -n "$PID_NUMBER" ] ; then
  echo "Sending SIGTERM to $PID_NUMBER irc-hybrid-client"
  kill -SIGTERM $PID_NUMBER
fi
IRC_HYBRID_CLIENT_PATH=$HOME/tmp/irc-hybrid-client.PID
PID_NUMBER=$(cat $IRC_HYBRID_CLIENT_PATH)
if [ -n "$PID_NUMBER" ] ; then
  echo "Sending SIGTERM to $PID_NUMBER irc-hybrid-client"
  kill -SIGTERM $PID_NUMBER
fi

There are bash scripts "restart.sh" and "restart2.sh" that can be used to restart after changes were made to credentials.json.

{
  "persistIrcMessageCache": true,
}
IRC_PERSIST_MESSAGE_CACHE=true
Log Files and File Rotation

Logging to disk file is enabled when the server is started with NODE_ENV=production, otherwise logging is sent to stdout. Log files are located in the "logs/" folder located in the repository base folder. The log folder will be created automatically if it does not exist.

HTTP access log events will be written to the file "logs/access.log". If log file rotation is enabled, linux logrotate type rotation will create access.log.1, access.log.2 up to access.log.5.

IRC raw message log events, if enabled in individual server configuration, will be written to the file "logs/irc.log". If log file rotation is enabled, linux logrotate type rotation will create irc.log.1, irc.log.2 up to irc.log.5.

Web server login events will be written to the file "logs/auth.log" Additions, modifications, or deletions from the IRC server list will be added to the auth.log file. The file auth.log is not subject to log file rotation

Optional log file rotation may enabled by assigning the "logRotationInterval" property or the "logRotationSize" property in credentials.json to the proper string value. Log rotate time interval available time units (s, m, h, d) are used to specify the interval string. (Example: '5m', '2h', '1d'). Minutes and hours are a time divisor, but the day interval is a simple timer that is re-initialized each time the application is restarted. Log rotate file size available time units (B, K, M, G) are used to specify the file size string. (Example: '100K', '1M'). Optionally either interval, size, both, or neither may be used. This will allow log file log rotation similar to Linux system files. For more information see rotating-file-stream documentation. In the case where neither interval nor size properties exist or both are empty strings, then no log rotation will occur, and file size management must be done manually.,

If the web server is started with env variable NODE_DEBUG_LOG=1, all log output will be directed to stdout. This is useful to view the logs in real time when debugging a server when NODE_ENV===production.

{
  "logRotationInterval": "7d",
  "logRotationSize": "1M",
}
SERVER_LOG_ROTATE_INTERVAL=7d
SERVER_LOG_ROTATE_SIZE=1M
HTTP Access Log Filter

HTTP requests are logged to logs/access.log. If the configuration property accessLogOnlyErrors is false or the property does not exist the HTTP access log will include all HTTP requests, else the access log will be filtered include only HTTP errors (status >= 400).

If the web server is started with NODE_ENV=development or NODE_DEBUG_LOG=1, the the accessLogOnlyErrors property will be ignored and all HTTP requests will be visible.

{
  "accessLogOnlyErrors": false,
}
SERVER_LOG_ONLY_ERRORS=false
Serve HTML Help Files

The git repository includes a /docs folder (this web page) containing static HTML files with help documentation. These are available on GitHub Pages. Optionally, the /docs repository folder maybe be included locally within the irc-hybrid-client web server at path "/irc/docs/". This is completely optional. To save disk space, it is not necessary to include the /docs folder in web server deployment, nor is it necessary to serve the folder, even if present.

User login will be required prior to viewing the help pages. If enabled, a button "View Documentation" will be added to the Info/License panel. Alternately, the path URL /irc/docs/ can be bookmarked. When not logged in, the help page will return status 403 Forbidden.

To enable the /docs file folder to be available at web path /irc/docs/, set the serveHtmlHelpDocs property to true. If the property does not exist due to an earlier version of credentials.json, no error will be issued and the files will not be served.

{
  "serveHtmlHelpDocs": true
}
IRC_SERVE_HTML_HELP_DOCS=true
Optional Custom Sound Files

The irc-hybrid-client program includes 3 sound files used to generate "beep" sounds when triggered by channel messages, own nickname, and private messages. The default sound files are named short-beep1.mp3, short-beep2.mp3, and short-beep3.mp3. Although the replacement files of the same filenames can be substituted manually, this could cause a merge conflict during git pull/merge operations. Three alternate custom filenames have been defined. The custom filenames have been included in the .gitignore file to avoid git merge conflicts.

The optional custom sound files may be used in either development version or the production minified version with files in the following locations.

secure-minify/sounds/custom-beep1.mp3 (Channel message, join)
secure-minify/sounds/custom-beep2.mp3 (Match Own Nickname)
secure-minify/sounds/custom-beep3.mp3 (Private Message)

secure/sounds/custom-beep1.mp3 (Channel message, join)
secure/sounds/custom-beep2.mp3 (Match Own Nickname)
secure/sounds/custom-beep3.mp3 (Private Message)

To enable the optional custom sounds set the property "customBeepSounds: true" in the credentials.json file or set the environment variable "IRC_CUSTOM_BEEP_SOUNDS=true" For backward compatibility, if this property does not exist in credentials.json due to an upgrade from previous version the default sound filenames will be used and no error will be generated.

{
  "customBeepSounds": true
}
IRC_CUSTOM_BEEP_SOUNDS=true
Optional Socks5 Proxy Support

In normal operation, the irc-hybrid-client web server will establish a direct TCP socket connection to the IRC server. Some users have dynamic IP addresses that change frequently. This can present difficulties when using an IRC client's IP address to authenticate user identity with services like NickServ and ChanServ. Some isolated network firewall configurations require a proxy server for internet access. Other users may be concerned about exposing their IP address for privacy or security reasons. One solution to this issue is to use an intermediate socks5 proxy server. In this case, the connection to the IRC server will originate from the remote IP address of the socks5 proxy server. The socks5 proxy concept involves a simple network address replacement. Therefore, socks5 connections themselves are not protected by encryption. The irc-hybrid-client supports TLS between IRC client and IRC server inside of socks5.

Each individual IRC server definition that uses the proxy must have a "proxy:true" set in the IRC server definition. When the socks5 proxy is disabled globally, the server's proxy property is ignored.

To globally enable use of a remote socks5 proxy server without authentication, update the configuration as shown in following example, changing address and port.

{
  "enableSocks5Proxy": true,
  "socks5Host": "192.168.0.1",
  "socks5Port": 1080,
  "socks5Username": null,
  "socks5Password": null  
}
IRC_ENABLE_SOCKS5_PROXY=false
IRC_SOCKS5_HOST=192.168.0.1
IRC_SOCKS5_PORT=1080
# IRC_SOCKS5_USERNAME=
# IRC_SOCKS5_PASSWORD=

To globally enable use of a remote socks5 proxy server with password authentication, update the configuration as shown in the following example. Note: This can expose socks5 authentication passwords in plain text. This issue can be addressed by passing the socks5 connection through a TLS encrypted VPN tunnel.

{
  "enableSocks5Proxy": true,
  "socks5Host": "192.168.0.1",
  "socks5Port": 1080,
  "socks5Username": "user1",
  "socks5Password": "xxxxxxxx"
} 
IRC_ENABLE_SOCKS5_PROXY=false
IRC_SOCKS5_HOST=192.168.0.1
IRC_SOCKS5_PORT=1080
IRC_SOCKS5_USERNAME=user1
IRC_SOCKS5_PASSWORD="xxxxxxxx"

Socks5 support was debugged using the dante-server apt package in Debian 10 using danted.conf configuration set to "socksmethod: none" (Not authenticated) and "socksmethod: username" (password authentication). Other authentication methods are not supported. Socks5 socket connections are handled internally using the npm package socks5-client.

IRC Socket Local Address

For host machines with multiple IP addresses, the outbound IRC socket may be bound to a specific local IP address. This will be the IP address shown to other IRC users who use the /WHOIS command on your nickname.

The intention of this feature is to allow multiple IRC clients on the same server to each use different unique IPV6 address. Many commercial VPS servers are capable of multiple IPV6 addresses within a specified range. Multiple IPV4 address are less common, but IPV4 will work if configured.

When an IPV4 or IPV6 address is specified as the IRC socket local address, all connections to IRC servers must use the same IPV4 or IPV6 family. It is possible that this may cause an issue for domain names that resolve to both IPV4 and IPV6 addresses. Many IRC networks provide family specific IRC domain names, such as "ipv6.dal.net" on DALnet.

The IRC socket local address does not impact the NodeJs web server. When the web server and websocket server are started, they will listen on all configured interfaces.

When the IRC client is configured to use an optional socks5 proxy, the local IP address is ignored.

To bind a local IP address to the IRC socket, set the "ircSocketLocalAddress" property to a string value containing a valid IPV4 or IPV6 numeric IP address. This feature is optional and it may be disabled by setting ircSocketLocalAddress to an empty string. For backward compatibility, if the property is not present, the feature is disabled and no error will be generated.

{
  "ircSocketLocalAddress": "fc00:10::1000"
} 
IRC_SOCKET_LOCAL_ADDRESS=fc00:10::1000
Optional Remote Login

The irc-hybrid-client is intended to run as a stand alone web server where a web browser can authenticate using a password entry form that is integral to the application. This is the default configuration as described in the sections above.

As an optional alternative, the irc-hybrid-client can be configured to use a remote authentication server. The intended purpose is to allow a single user account to grant access to multiple servers on a home network. This would allow a user to gain access to several instances of irc-hybrid-client. This may be useful if multiple irc-hybrid-client instances are run concurrently while connected to different IRC networks.

An independent authorization server (collab-auth) was written in parallel with this irc-hybrid-client project. It uses a custom implementation of Oauth 2.0.

In general terms, the authorization workflow will operate as follows: When a user attempts to load the irc-hybrid-client web page without a valid login cookie, the user's browser will be redirected to the authorization server. The user will authenticate their identity by entry of username and password. The user's web browser will then be redirected back to the irc-hybrid-client with a temporary authorization code. The irc-hybrid-client will submit the code to the authorization server. A new Oauth 2.0 access token will be created and returned to the irc-hybrid-client web server. The irc-hybrid-client server will then validate and decode the token by sending the token to the authorization server, which will return token meta-data to the irc-hybrid-client. The irc-hybrid-client will extract a list of scope values from the token meta-data, and compare the token scopes to the list of scopes in the irc-hybrid-client configuration. If the users token is successfully validated and at least 1 matching scope found, the user's cookie will then be designated as authorized. The IRC page will then load, and the user can participate on IRC.

Prerequisites

The following items are required. These are beyond the scope of these instructions, so it is assumed you are familiar with this type of web site setup.

Scope definitions

The Scope value is the primary determiner to specify if a given user will have access to a specific irc-hybrid-client instance.

The irc-hybrid-client configuration will contain a single scope or multiple scope values in the "remoteScope" property of the credentials.json file. When more than one irc-hybrid-client is running at the same time, different scope values will determine which user can access which irc-hybrid-client instance.

In order for a irc-hybrid-client scope to be valid, it must be listed as one of the scopes in the "allowedScope" list of the irc-hybrid-client's client credentials for the authorization server.

An authorization server user account will also have one or more scopes listed in the user's "role". In order to gain access to an irc-hybrid-client, at least one of the user's role entries must match an entry in the irc-hybrid-client configuration.

In the case where there is only 1 user and 1 irc-hybrid-client, then a single scope value may be used in the user's role, the client's allowedScope, and the irc-hybrid-client remoteScope.

Client Account Configuration

Under Oauth 2.0, "client" credentials are assigned to a web server or other network resource. The purpose of client credentials is to grant permission to the web server to interact with the authorization server.

clientId/clientSecret: Each client account will need a unique client id and client secret. The clientId and client secret are used to authenticate an instance of irc-hybrid-client to the authentication server. One client credential can be used on multiple irc-hybrid-clients or one unique client can be created for each irc-hybrid-client, depending on the complexity of the overall setup.

allowedScope: The first scope value "auth.token" is always required. It is a standard value that is used to grant the irc-hybrid-client permission to request access tokens from the authentication server. This is followed by a comma separated list of unique scope values. The list must include the sum of all scope values used in all irc-hybrid-clients that share the client credentials. This can be thought of as a list of possible scopes that irc-hybrid-clients are allowed to use.

allowedRedirectURI: The Oauth 2.0 authentication workflow includes a browser redirect to the URL address of the authorization server. After user authentication, the authentication server will redirect the user's browser back to the URL address of the specific irc-hybrid-client server that had initiated the authentication workflow. In order to prevent malicious redirects, the authorization server will only allow a login callback to a redirectURI that is listed in a list of allowedRedirectURI in the client credentials. During the authentication workflow, the authorization server will reject any redirect with a callback addresses that is not an exact match in this list.

User Account Configuration

Administration of user accounts is explained in the collab-auth documentation. For a user to be granted access to a specific irc-hybrid-client instance, the role of the user account must include one of the remoteScope values from the irc-hybrid-client configuration.

Create a new user account, or edit an existing user account. In the field marked "role" add one or more scope designations from the irc-hybrid-client configuration. In this case, irc.all is used.

irc-hybrid-client Configuration

For a specific instance of irc-hybrid-client, the configuration is located in the "credentials.json" file or alternately configured using environment variables. Only the properties related to remote login will be discussed in this section.

When using remote login, the local user account described above is not used and the local user account entries may be omitted from the configuration. If you want to switch back and forth between local login and remote login, you may leave the local user account in the configuration. The local user definitions specified above will not be functional when remote login is enabled. If present, the local users definitions will not impact remote login.

enableRemoteLogin/OAUTH2_ENABLE_REMOTE_LOGIN: This is a boolean flag. If the property does not exist or the enableRemoteLogin property is false, the default internal login will be enabled. When set to true, remote login is enabled.

remoteAuthHost/OAUTH2_REMOTE_AUTH_HOST: This is the address of the remote authorization server. Hostnames must specify http or https. When using non-standard port numbers, the port should be specified. With TLS standard port 443 the port may be omitted.

remoteCallbackHost/OAUTH2_REMOTE_CALLBACK_HOST: This is address of this irc-hybrid-client web server. After successful entry of username and password, the authorization server will redirect the web browser back to this address with an authorization code. the value must match the allowedRedirectURI property defined in the client account on the authorization server.

clientId/OAUTH2_REMOTE_CLIENT_ID: The client id must exactly match the client credentials as defined in the authorization server client account.

clientSecret/OAUTH2_REMOTE_CLIENT_SECRET: The client secret must exactly match the client credentials as defined in the authorization server client account. Take precautions to protect the client credentials from accidental disclosure as this could grant unauthorized access to the authorization server.

remoteScope/OAUTH2_REMOTE_SCOPE: The remoteScope property may be a single string value, or it may be an array of strings. The OAUTH2_REMOTE_SCOPE environment variable may be assigned as one string value, or multiple string values separated by commas without spaces. Any authenticated user may access an instance of irc-hybrid-client if one of the remoteScope values here is an exact match to at least one of the scopes defined in the user's role and the client allowedScope. To clarify, the scope is a 3 way match, the client account's "allowedScope", the user account's "role", and the irc-hybrid-client server's "remoteScope" or "OAUTH2_REMOTE_SCOPE" value for the irc-hybrid-client server's scope.

{
  ...
  
  "loginUsers": [ ],
  "enableRemoteLogin": true,
  "remoteAuthHost": "http://127.0.0.1:3500",
  "remoteCallbackHost": "http://localhost:3003",
  "remoteClientId": irc_client_1,
  "remoteClientSecret": "xxxxxxxxxxxxxxxxxxxxxxxx",
  "remoteScope": [
    "irc.all",
    "irc.demo1"
  ]
}
OAUTH2_ENABLE_REMOTE_LOGIN=true
OAUTH2_REMOTE_AUTH_HOST=http://127.0.0.1:3500
OAUTH2_REMOTE_CALLBACK_HOST=http://localhost:3003
OAUTH2_REMOTE_CLIENT_ID=irc_client_1
OAUTH2_REMOTE_CLIENT_SECRET="xxxxxxxxxxxxxxxxxxxxxxxx"
OAUTH2_REMOTE_SCOPE=irc.all,irc.two
Other Oauth Providers

It is unlikely that irc-hybrid-client will work with other generic Oauth 2.0 providers without modification to the middlewares/remote-authentication.mjs javascript file. Both irc-hybrid-client and collab-auth were written concurrently by the same author.