The new TripleA dice server re-written in JavaScript.
In order to be able to run the server you need to have a couple of things installed on your system:
node.js
>= 10yarn
postgres
>= 10 After those are installed on your system you can follow the steps below to get yourself up and running. The steps assume node and yarn are on thePATH
of your system, if that's not the case, you need to replacenode
andyarn
with the fully-qualified path name to the executable.
- Clone this Repository in a directory of your choice.
- Open a terminal and navigate to the newly checked out directory.
- Run
yarn install
, this will resolve all dependencies for you and install them innode_modules
-
- Generate an RSA key-pair. If you have installed
openssl
and it's on your PATH, you can simply runyarn generate-keypair
, which will create the filesprivkey.pem
andpubkey.pem
in the current directory. - On production systems you should move them into a "save directory" and (at least on UNIX-like systems) restrict read access of the private key to the user that's going to run the server and root.
- Generate an RSA key-pair. If you have installed
-
- Create a file
config.json
which contains all information the server needs to start. - Alternatively those configuration options can be passed via CLI directly or as environment variables. Check the nconf docs for more information.
- The config files' layout will be explained below.
- Create a file
- Create a database in Postgres to be used by the server.
{
"port": 7654,
"database": {
"username": "postgres",
"password": "",
"host": "localhost",
"port": 5432,
"database": "dicedb"
},
"email": {
"smtp": {
"host": "smtp.provider.com",
"port": 587,
"auth": {
"user": "your.email@provider.com",
"pass": "super secret password no one will ever guess"
}
},
"display": {
"sender": "\"Display Name\" <your.email@provider.com>",
"server": {
"protocol": "http",
"host": "localhost",
"port": 7654,
"baseurl": ""
}
}
},
"keys": {
"private": "./privkey.pem",
"public": "./pubkey.pem"
}
}
port
: The port node.js will listen on. Required.database
: Details about the database connection. Required.username
: Username to authenticate with the database. Default:postgres
.password
: Password to authenticate with the database. Defaults to an empty String.host
: Hostname to connect to the database. Defaultlocalhost
.port
: Port to connect to the database. Default5432
.database
: Name of the database to use, this should be the database you created in the one-time setup. Defaultdicedb
.
email
: Settings that are used by the EmailManager. Required.smtp
: Nodemailer SMTP Configuration, this object will be passed directly to Nodemailer without any further processing. Check the Nodemailer Docs. If you need a service to test emails locally you can use Ethereal, a dummy email service that doesn't actually sends emails but simulates a fully-featured SMTP server.display
: Display settings how the server will refer to itself in emails.sender
: The Entry for theFrom:
field in the email. The actual email should be the correct one, otherwise the emails will likely land in SPAM Folders. Required.server
: Settings that define how the server will refer to itself in E-Mails. Required.protocol
: The protocol that should be used to connect to this server. Defaulthttp
.host
: The hostname that should be used to refer to this server, ideally a domain. Defaultlocalhost
.port
: The port that should be used to connect to this server, if used behind a reverse-proxy this should be the public port. Default:7654
.baseurl
: In case your server is in a non-root installation, set this to the folder name. (Exampleyourserver.com/dice
->/dice
.) Defaults to an empty String.
keys
:private
: Path to the private key used to sign dice rolls. Required.public
: Path to the public key used to sign dice rolls. Required.
In order to start the server run
node dice-server.js
It can be terminated using SIGTERM
, i.e. Ctrl+C
.
In order to run all local tests and eslint, you can simply run
yarn test
This is also the command that will be executed by Travis.
The dice server is divided into 2 seperate routers.
The REST Service handles all calls under /api
.
All other requests are handled by the frontend which basically wraps the API calls with a nice UI.
All of the requests return JSON in the same format. When successful:
{
"status": "OK",
"result": {
"some info": "some value",
"other info": true
}
}
result
is optional, if it's not present this simply means that the server has no additional information for this request.
On Error:
{
"status": "Error",
"errors": ["List", "of", "error", "messages"]
}
- POST
/api/roll
:- Required Parameters (POST Body, urlencoded):
max
Integer. Specifies the highest outcome for each roll, must be <= 100.times
Integer. Specifies how many dice should be rolled, must be <= 100.email1
String. The first email to send the notification email to. This email needs to be registered.email2
String. The second email to send the notification to. This email needs to be registered.
- Generates
times
random numbers with a value in[1, max]
. - Result
dice
Integer Array: An array of the rolled dice.date
Integer: The current UNIX timestamp with millisecond precision. Taken into account for the signature so the signature can't be reused in the future.signature
: The base64-encoded signature verifying the integrity of the rolled dice.
- Required Parameters (POST Body, urlencoded):
- GET
/api/verify/:token
::token
Parameter:- This parameter is actually a base64-encoded, urlencoded JSON string of roughly this scheme:
{ "dice": [1, 2, 3], "date": 121332, "signature": "base64encodedsignature" }
. dice
Integer Array: An array of the dice rolls to be verified.date
Integer: A Unix Timestamp of the exact millisecond the original request was made. Important for the signature, and could potentially be used to check if this signature was made with a legacy certificate.signature
String: A base64-encoded RSA signature that can be verified by the server.- Result:
valid
: A Boolean indicating if the integrity could be confirmed.
- This parameter is actually a base64-encoded, urlencoded JSON string of roughly this scheme:
- POST
/register
:- Required Parameters (POST Body, urlencoded):
email
String: The email a confirmation email will be sent to.
- A request to this endpoint sends an email to the specified email with a random 512-bit token that is only saved in the RAM and will expire after a maximum amount of 60 minutes.
- Required Parameters (POST Body, urlencoded):
- POST
/register/:token
::token
Parameter:- This parameter is a base64-encoded random number to verify that the person registering the email actually has access.
- If the token is wrong, the actual token automatically expires and a new confirmation email needs to be sent.
- Required Parameters (POST Body, urlencoded):
email
String: The email to compare the token with.
- POST
/unregister
- Required Parameters (POST Body, urlencoded):
email
String: The email to remove from the database.
- Required Parameters (POST Body, urlencoded):
The Frontend is being served using templates and the liquid format. The same template engine is used for emails as well. Basically all pages consist of a classic HTML form that gets replaced with a responsive AJAX system if JavaScript is available.
- GET
/
:- The index page where users can register their emails.
- GET
/verify
:- The page the emails redirect to to verify your emails.
- Parameters:
token
String: The token to pass to the/api/verify
endpoint.
- GET
/register
:- The page the "confirm-registration-email" redirects to to press a confirm button in a user-friendly way.
- Parameters:
email
String: The email to confirm the registration for.token
String: The token to pass to the/api/register/:token
endpoint.
- GET
/unregister
- The page where users can unregister their email.
- Paramaters:
email
String, optional: The email to remove from the database, used to pre-fill the form.