diff --git a/client/src/elm/MassiveDecks/Strings.elm b/client/src/elm/MassiveDecks/Strings.elm
index 0f72dc1..016c377 100644
--- a/client/src/elm/MassiveDecks/Strings.elm
+++ b/client/src/elm/MassiveDecks/Strings.elm
@@ -6,128 +6,6 @@ module MassiveDecks.Strings exposing (MdString(..))
import MassiveDecks.Pages.Lobby.GameCode as GameCode exposing (GameCode)
-
-{- Translator notes
-
- This file contains a list of every string in the game, along with a description to help translators.
- Please reference it while translating.
-
- Adding to the game:
-
- The first note is that adding the translation to the game itself is somewhat technical, if you struggle with it,
- please feel free to make a bug and get a developer to help you - you can do the translation itself more simply
- and a developer can do the work of adding the translation, and skip this section.
-
- The best way to get started is to copy the "Languages/En.elm" translation. Add the language to the lists in both
- "Languages/Model.elm" and "Languages.elm" (at the top and at the bottom in "pick").
-
- e.g: Adding English (Great Britain). The IETF language tag for this is en-GB, so we'll use EnGB as the name.
-
- In "Languages/Model.elm":
- type Language
- = En
- ...
- | EnGB -- Add this line.
-
- In "Languages.elm":
- languages : List Language
- languages =
- [ En
- ...
- , EnGB -- Add this line.
- ]
-
- ...
-
- pack : Language -> Translation.Pack
- pack language =
- case language of
- En ->
- EnLang.pack
-
- ...
-
- EnGB -> -- Add this line.
- EnGBLang.pack -- Add this line.
-
- This should result in a new language that works exactly as English does. You can now start changing the metadata.
-
- In "Languages/EnGB.elm" (replacing EnGB with your language):
- pack : Translation.Pack
- pack =
- { code = "en-GB" -- Change this to the IETF language tag for the language.
- , name = English
- , translate = translate
- }
-
- You will notice that we also need a string describing the language. You can do this in this file.
-
- In this file:
- -- Language Names
- | English -- The name of the English language (no specific dialect).
- ...
- | BritishEnglish -- Add this line.
-
- Note that once you do this, you'll need to add a translation for this to every other language as well.
-
- In "Languages/EnGB.elm" (replacing EnGB with your language):
- pack : Translation.Pack
- pack =
- { code = "en-GB"
- , name = BritishEnglish -- Change this to your new string.
- , translate = translate
- }
-
- You can now start changing the actual strings. These are created either from raw text or references to other
- strings:
- MassiveDecks ->
- [ Text "Massive Decks" ]
-
- WhatIsThis ->
- [ Text "What is ", Ref MassiveDecks, Text "?" ]
-
- This will render was "What is Massive Decks?", but if you changed "MassiveDecks" to "Test", it would result in
- "What is Test?". This allows you to avoid translating the same thing many times and allows the text to be
- enhanced with things like links automatically.
-
- In general, you should be able to just translate the raw text in quotes and shuffle things around. The more
- complex parts should pretty much remain as-is.
-
- Note that some strings take arguments:
- UserConnected { username } ->
- [ Text username, Text " has reconnected to the game." ]
-
- Note that some arguments are numbers, and these have to be converted to strings:
- Score { total } ->
- [ Text (String.fromInt total) ]
-
- Note this is code, rather than configuration, so complex operations can be performed. "Plural" is an example
- of this, as is "asWord". If you are not a programmer, these may be awkward - please feel free to explain the
- behaviour you need in a bug to get a developer to help out for awkward cases like different grammar rules for
- plurals, etc...
-
- Terminology:
-
- Note the difference between "Players" and "Users". Players play the game, users includes both players and
- spectators, and is the more general term.
-
- A play code is a Cardcast-specific thing that specifies a deck on their platform, and is not the same thing
- as a game code, which allows a user to join a game in Massive Decks.
-
- Other Notes:
-
- Please use unicode characters as appropriate. E.g: the em-dash (—) (which is particularly awkward to notice
- in monospaced fonts, real quotes (“”), apostrophes (’) and ellipsis (…).
-
- Likewise, unicode offers us valuable hinting tools to control hyphenation and line breaking:
- A unicode soft hyphen (\u{00AD}) indicated a good point in a word to break it if needed.
- A unicode zero-width space (\u{200B}) can do the same thing without a hyphen (hyphens should be preferred,
- however, ).
- For the reverse (no line breaking between words), use a unicode non-breaking space (\u{00A0}).
-
--}
-
-
{-| Each type represents a message that may be shown to the user. Some have arguments that are variable but should be
included in some form in the message.
-}
diff --git a/client/src/html/index.html b/client/src/html/index.html
index 2d3412b..c735c61 100644
--- a/client/src/html/index.html
+++ b/client/src/html/index.html
@@ -14,8 +14,6 @@
-
-
diff --git a/server/Dockerfile b/server/Dockerfile
index 50ecc7c..7cce852 100644
--- a/server/Dockerfile
+++ b/server/Dockerfile
@@ -12,7 +12,9 @@ LABEL maintainer="team@rereadgames.com"
ARG BUILD_DATE
ARG VCS_REF
-ARG VERSION
+ARG VERSION=dev
+
+ENV MD_VERSION $VERSION
LABEL org.label-schema.name="massivedecks/server"
LABEL org.label-schema.description="The web server for Massive Decks, a comedy party game."
diff --git a/server/config.json5 b/server/config.json5
index 53201a8..924146a 100644
--- a/server/config.json5
+++ b/server/config.json5
@@ -3,9 +3,12 @@
// You can use `npm run generate-secret` to generate a suitable value.
// Note that changes to this value will kick all users from all games.
secret: "CHANGE ME",
+ // This will be overwritten by the environment variable MD_SECRET, if set.
- // The port to serve on. This should be behind a proxy.
- port: 8081,
+ // The port to serve on. Note this should always be behind a reverse proxy.
+ listenOn: 8081,
+ // It is also possible to listen on a unix socket.
+ // listenOn: "/tmp/sock",
// The path this is hosted behind - only relevant when behind a reverse proxy, this won't actually host on a different
// path. This should always have a trailing slash if it isn't empty, and never one at the start.
@@ -84,8 +87,7 @@
checkAfter: "PT5M"
},
- // The version of Massive Decks (displayed in the footer on the main page, and given in bug reports).
- // Please don't change this unless you are running a custom version, and if so use a unique prefix, so it is clear
- // in bug reports.
+ // The version of Massive Decks.
+ // This will be overwritten by the environment variable MD_VERSION, if set.
version: "dev"
}
diff --git a/server/package-lock.json b/server/package-lock.json
index eefa3e9..b8927b1 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "server",
- "version": "1.0.0",
+ "version": "2.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -145,6 +145,15 @@
"@types/node": "*"
}
},
+ "@types/helmet": {
+ "version": "0.0.43",
+ "resolved": "https://registry.npmjs.org/@types/helmet/-/helmet-0.0.43.tgz",
+ "integrity": "sha512-45cU1ZW3L6ZxPQzAB597nl7OfUr14ceUWaQRoiByGFAjZlCQRvaEFC4Vv84lLWsFCYVWLU+raz+bIHrVBNTdRw==",
+ "dev": true,
+ "requires": {
+ "@types/express": "*"
+ }
+ },
"@types/json-stable-stringify": {
"version": "1.0.32",
"resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz",
@@ -666,6 +675,11 @@
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
"dev": true
},
+ "camelize": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
+ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
+ },
"capture-stack-trace": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
@@ -891,6 +905,11 @@
"safe-buffer": "5.1.2"
}
},
+ "content-security-policy-builder": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.0.0.tgz",
+ "integrity": "sha512-j+Nhmj1yfZAikJLImCvPJFE29x/UuBi+/MWqggGGc515JKaZrjuei2RhULJmy0MsstW3E3htl002bwmBNMKr7w=="
+ },
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
@@ -943,6 +962,11 @@
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
"dev": true
},
+ "dasherize": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
+ "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -1036,6 +1060,11 @@
"kuler": "1.0.x"
}
},
+ "dns-prefetch-control": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz",
+ "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI="
+ },
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -1045,6 +1074,11 @@
"esutils": "^2.0.2"
}
},
+ "dont-sniff-mimetype": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz",
+ "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g="
+ },
"dot-prop": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
@@ -1117,13 +1151,13 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
- "version": "5.16.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
- "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.0.0.tgz",
+ "integrity": "sha512-SrrIfcd4tOgsspOKTSwamuTOAMZOUigHQhVMrzNjz4/B9Za6SHQDIocMIyIDfwDgx6MhS15nS6HC8kumCV2qBQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "ajv": "^6.9.1",
+ "ajv": "^6.10.0",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
@@ -1131,18 +1165,19 @@
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
- "espree": "^5.0.1",
+ "espree": "^6.0.0",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
- "glob": "^7.1.2",
+ "glob-parent": "^3.1.0",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.2.2",
- "js-yaml": "^3.13.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.11",
@@ -1150,7 +1185,6 @@
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
- "path-is-inside": "^1.0.2",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
@@ -1183,17 +1217,17 @@
}
},
"ms": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
- "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"eslint-config-prettier": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.3.0.tgz",
- "integrity": "sha512-sZwhSTHVVz78+kYD3t5pCWSYEdVSBR0PXnwjDRsUs8ytIrK8PLXw+6FKp8r3Z7rx4ZszdetWlXYKOHoUrrwPlA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-5.0.0.tgz",
+ "integrity": "sha512-c17Aqiz5e8LEqoc/QPmYnaxQFAHTx2KlCZBPxXXjEMmNchOLnV/7j0HoPZuC+rL/tDC9bazUYOKJW9bOhftI/w==",
"dev": true,
"requires": {
"get-stdin": "^6.0.0"
@@ -1231,9 +1265,9 @@
"dev": true
},
"espree": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
- "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz",
+ "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
@@ -1332,6 +1366,11 @@
}
}
},
+ "expect-ct": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz",
+ "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g=="
+ },
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
@@ -1515,6 +1554,11 @@
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
"integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg=="
},
+ "feature-policy": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
+ "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ=="
+ },
"fecha": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
@@ -1639,6 +1683,11 @@
"map-cache": "^0.2.2"
}
},
+ "frameguard": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz",
+ "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g=="
+ },
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -2350,6 +2399,76 @@
"resolved": "https://registry.npmjs.org/hashids/-/hashids-1.2.2.tgz",
"integrity": "sha512-dEHCG2LraR6PNvSGxosZHIRgxF5sNLOIBFEHbj8lfP9WWmu/PWPMzsip1drdVSOFi51N2pU7gZavrgn7sbGFuw=="
},
+ "helmet": {
+ "version": "3.18.0",
+ "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.18.0.tgz",
+ "integrity": "sha512-TsKlGE5UVkV0NiQ4PllV9EVfZklPjyzcMEMjWlyI/8S6epqgRT+4s4GHVgc25x0TixsKvp3L7c91HQQt5l0+QA==",
+ "requires": {
+ "depd": "2.0.0",
+ "dns-prefetch-control": "0.1.0",
+ "dont-sniff-mimetype": "1.0.0",
+ "expect-ct": "0.2.0",
+ "feature-policy": "0.3.0",
+ "frameguard": "3.1.0",
+ "helmet-crossdomain": "0.3.0",
+ "helmet-csp": "2.7.1",
+ "hide-powered-by": "1.0.0",
+ "hpkp": "2.0.0",
+ "hsts": "2.2.0",
+ "ienoopen": "1.1.0",
+ "nocache": "2.1.0",
+ "referrer-policy": "1.2.0",
+ "x-xss-protection": "1.1.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ }
+ }
+ },
+ "helmet-crossdomain": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz",
+ "integrity": "sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg=="
+ },
+ "helmet-csp": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.1.tgz",
+ "integrity": "sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ==",
+ "requires": {
+ "camelize": "1.0.0",
+ "content-security-policy-builder": "2.0.0",
+ "dasherize": "2.0.0",
+ "platform": "1.3.5"
+ }
+ },
+ "hide-powered-by": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz",
+ "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys="
+ },
+ "hpkp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
+ "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI="
+ },
+ "hsts": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz",
+ "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==",
+ "requires": {
+ "depd": "2.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ }
+ }
+ },
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
@@ -2375,6 +2494,11 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
+ "ienoopen": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz",
+ "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ=="
+ },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -2431,9 +2555,9 @@
"dev": true
},
"inquirer": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
- "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz",
+ "integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==",
"dev": true,
"requires": {
"ansi-escapes": "^3.2.0",
@@ -3141,6 +3265,11 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
+ "nocache": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
+ "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
+ },
"nodemon": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz",
@@ -3473,6 +3602,11 @@
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
"dev": true
},
+ "platform": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz",
+ "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q=="
+ },
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -3611,6 +3745,11 @@
"readable-stream": "^2.0.2"
}
},
+ "referrer-policy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
+ "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
+ },
"regex-not": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -4124,9 +4263,9 @@
}
},
"table": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz",
- "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==",
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz",
+ "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==",
"dev": true,
"requires": {
"ajv": "^6.9.1",
@@ -4342,9 +4481,9 @@
}
},
"typescript-json-validator": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/typescript-json-validator/-/typescript-json-validator-2.2.0.tgz",
- "integrity": "sha512-F+swgGAA5CrwjL6cUHsRzA9e29g2LWZaszhoJTXn70ks/KCYVG0RuvkdeKe+IcbKNzSfD9lwEGgRo0cinZ3YCw==",
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/typescript-json-validator/-/typescript-json-validator-2.2.2.tgz",
+ "integrity": "sha512-K9kBDRhKj/sg7OK/gBqDYdEfOEH/7Y1Qi6eIzxCh7h8M+fRtmptX3HqHPDUVnjkCrzZeY+EkQk09l+4l2sW0Hw==",
"dev": true,
"requires": {
"@types/ajv": "^1.0.0",
@@ -4698,6 +4837,11 @@
"resolved": "https://registry.npmjs.org/wu/-/wu-2.1.0.tgz",
"integrity": "sha1-fnLj+6I+D/Zp3dU34chX09SxYU8="
},
+ "x-xss-protection": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz",
+ "integrity": "sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg=="
+ },
"xdg-basedir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
diff --git a/server/package.json b/server/package.json
index f974fe8..66268d5 100644
--- a/server/package.json
+++ b/server/package.json
@@ -1,6 +1,6 @@
{
"name": "server",
- "version": "1.0.0",
+ "version": "2.0.0",
"description": "Massive Decks server.",
"main": "dist/index.js",
"scripts": {
@@ -27,6 +27,7 @@
"express-ws": "^4.0.0",
"generic-pool": "^3.7.1",
"hashids": "^1.2.2",
+ "helmet": "^3.18.0",
"http-status-codes": "^1.3.2",
"json5": "^2.1.0",
"jsonwebtoken": "^8.5.1",
@@ -43,19 +44,20 @@
"@types/express-ws": "^3.0.0",
"@types/generic-pool": "^3.1.9",
"@types/hashids": "^1.0.30",
+ "@types/helmet": "^0.0.43",
"@types/json5": "0.0.30",
"@types/jsonwebtoken": "^8.3.2",
"@types/source-map-support": "^0.5.0",
"@types/uuid": "^3.4.4",
- "@types/wu": "latest",
+ "@types/wu": "^2.1.39",
"@typescript-eslint/eslint-plugin": "^1.10.2",
"@typescript-eslint/parser": "^1.10.2",
- "eslint": "^5.16.0",
- "eslint-config-prettier": "^4.3.0",
+ "eslint": "^6.0.0",
+ "eslint-config-prettier": "^5.0.0",
"eslint-plugin-prettier": "^3.1.0",
"nodemon": "^1.19.1",
"prettier": "1.18.2",
"typescript": "^3.5.2",
- "typescript-json-validator": "^2.2.0"
+ "typescript-json-validator": "^2.2.2"
}
}
diff --git a/server/src/ts/action/game-action/player/submit.ts b/server/src/ts/action/game-action/player/submit.ts
index 98a60d8..533dff5 100644
--- a/server/src/ts/action/game-action/player/submit.ts
+++ b/server/src/ts/action/game-action/player/submit.ts
@@ -76,7 +76,7 @@ export const handle: gameAction.Handler = (
if (timeout !== undefined) {
timeouts.push({
timeout: timeout,
- after: server.config.timeouts.nextRoundDelay
+ after: server.config.timeouts.finishedPlayingDelay
});
}
return { lobby, events, timeouts };
diff --git a/server/src/ts/config.ts b/server/src/ts/config.ts
index 70514ea..88241a1 100644
--- a/server/src/ts/config.ts
+++ b/server/src/ts/config.ts
@@ -7,7 +7,7 @@ type ParsedDuration = number;
export interface Config {
secret: string;
- port: number;
+ listenOn: number | string; // Port or unix socket path.
basePath: string;
version: string;
timeouts: Timeouts;
@@ -21,6 +21,7 @@ export type Unparsed = Config;
type Timeouts = {
timeoutCheckFrequency: D;
disconnectionGracePeriod: D;
+ finishedPlayingDelay: D;
nextRoundDelay: D;
} & { [key: string]: D };
diff --git a/server/src/ts/index.ts b/server/src/ts/index.ts
index 7f6b488..8315f89 100644
--- a/server/src/ts/index.ts
+++ b/server/src/ts/index.ts
@@ -23,6 +23,7 @@ import * as userDisconnect from "./timeout/user-disconnect";
import * as user from "./user";
import * as token from "./user/token";
import * as checkAlive from "./action/initial/check-alive";
+import helmet from "helmet";
sourceMapSupport.install();
@@ -41,8 +42,19 @@ async function main(): Promise {
(await promisify(fs.readFile)("config.json5")).toString()
) as serverConfig.Unparsed);
+ const envSecret = process.env.MD_SECRET;
+ if (envSecret !== undefined) {
+ config.secret = envSecret;
+ }
+
+ const envVersion = process.env.MD_VERSION;
+ if (envVersion !== undefined) {
+ config.version = envVersion;
+ }
+
const { app } = ws(express());
+ app.use(helmet());
app.set('trust proxy', true);
const environment = app.get("env");
@@ -187,8 +199,8 @@ async function main(): Promise {
.loadFromStore(state)
.catch(error => logging.logException("Error running store tasks:", error));
- app.listen(config.port, () =>
- logging.logger.info(`Serving on port ${config.port}.`)
+ app.listen(config.listenOn, () =>
+ logging.logger.info(`Listening on ${config.listenOn}.`)
);
}
diff --git a/server/tsconfig.json b/server/tsconfig.json
index c45b2ec..2da3986 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -16,7 +16,7 @@
"outDir": "./dist", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
- // "incremental": true, /* Enable incremental compilation */
+ "incremental": true, /* Enable incremental compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
"removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */