Added redis cache to help speed up requests for user data and communities. Prevented multiple reports for a single post being created from one user

This commit is contained in:
Jemma 2024-04-20 16:59:03 -05:00
parent b5da8169db
commit 905ba0f737
13 changed files with 450 additions and 43 deletions

View File

@ -29,5 +29,9 @@
"key": "",
"secret": ""
}
}
},
"redis": {
"host": "localhost",
"port": 6379
}
}

279
package-lock.json generated
View File

@ -13,11 +13,13 @@
"aws-sdk": "^2.1192.0",
"body-parser": "^1.19.0",
"colors": "^1.4.0",
"connect-redis": "^7.1.1",
"cookie-parser": "^1.4.5",
"crc": "^4.3.2",
"date-fns": "^2.29.3",
"express": "^4.17.1",
"express-rate-limit": "^6.7.0",
"express-session": "^1.18.0",
"fs-extra": "^9.0.1",
"hashmap": "^2.4.0",
"image-pixels": "^1.1.1",
@ -32,6 +34,7 @@
"node-snowflake": "0.0.1",
"pako": "^2.0.2",
"pngjs": "^6.0.0",
"redis": "^4.6.13",
"sharp": "^0.31.3",
"tga": "^1.0.4",
"xml2js": "^0.4.23",
@ -1053,6 +1056,59 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
},
"node_modules/@redis/bloom": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/client": {
"version": "1.5.14",
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz",
"integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==",
"dependencies": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
"yallist": "4.0.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/@redis/graph": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/json": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz",
"integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/search": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz",
"integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/time-series": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz",
"integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@smithy/abort-controller": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.12.tgz",
@ -2609,6 +2665,14 @@
"node": ">=0.8"
}
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
@ -2694,6 +2758,17 @@
"typedarray": "^0.0.6"
}
},
"node_modules/connect-redis": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.1.tgz",
"integrity": "sha512-M+z7alnCJiuzKa8/1qAYdGUXHYfDnLolOGAUjOioB07pP39qxjG+X9ibsud7qUBc4jMV5Mcy3ugGv8eFcgamJQ==",
"engines": {
"node": ">=16"
},
"peerDependencies": {
"express-session": ">=1"
}
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -3615,6 +3690,56 @@
"express": "^4 || ^5"
}
},
"node_modules/express-session": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz",
"integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==",
"dependencies": {
"cookie": "0.6.0",
"cookie-signature": "1.0.7",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-headers": "~1.0.2",
"parseurl": "~1.3.3",
"safe-buffer": "5.2.1",
"uid-safe": "~2.1.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/express-session/node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express-session/node_modules/cookie-signature": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="
},
"node_modules/express-session/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/express-slow-down": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/express-slow-down/-/express-slow-down-1.4.0.tgz",
@ -4020,6 +4145,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/generic-pool": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
"engines": {
"node": ">= 4"
}
},
"node_modules/get-assigned-identifiers": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
@ -5785,6 +5918,14 @@
"quote-stream": "bin/cmd.js"
}
},
"node_modules/random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -5847,6 +5988,19 @@
"node": ">=8.10.0"
}
},
"node_modules/redis": {
"version": "4.6.13",
"resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz",
"integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==",
"dependencies": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.5.14",
"@redis/graph": "1.1.1",
"@redis/json": "1.0.6",
"@redis/search": "1.1.6",
"@redis/time-series": "1.0.5"
}
},
"node_modules/regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@ -6681,6 +6835,17 @@
"node": ">=14.17"
}
},
"node_modules/uid-safe": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
"dependencies": {
"random-bytes": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@ -7839,6 +8004,46 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
},
"@redis/bloom": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
"requires": {}
},
"@redis/client": {
"version": "1.5.14",
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.14.tgz",
"integrity": "sha512-YGn0GqsRBFUQxklhY7v562VMOP0DcmlrHHs3IV1mFE3cbxe31IITUkqhBcIhVSI/2JqtWAJXg5mjV4aU+zD0HA==",
"requires": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
"yallist": "4.0.0"
}
},
"@redis/graph": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
"requires": {}
},
"@redis/json": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.6.tgz",
"integrity": "sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==",
"requires": {}
},
"@redis/search": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.6.tgz",
"integrity": "sha512-mZXCxbTYKBQ3M2lZnEddwEAks0Kc7nauire8q20oA0oA/LoA+E/b5Y5KZn232ztPb1FkIGqo12vh3Lf+Vw5iTw==",
"requires": {}
},
"@redis/time-series": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.5.tgz",
"integrity": "sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==",
"requires": {}
},
"@smithy/abort-controller": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.12.tgz",
@ -9014,6 +9219,11 @@
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
"cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="
},
"color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
@ -9081,6 +9291,12 @@
"typedarray": "^0.0.6"
}
},
"connect-redis": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-7.1.1.tgz",
"integrity": "sha512-M+z7alnCJiuzKa8/1qAYdGUXHYfDnLolOGAUjOioB07pP39qxjG+X9ibsud7qUBc4jMV5Mcy3ugGv8eFcgamJQ==",
"requires": {}
},
"content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -9796,6 +10012,38 @@
"integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==",
"requires": {}
},
"express-session": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.0.tgz",
"integrity": "sha512-m93QLWr0ju+rOwApSsyso838LQwgfs44QtOP/WBiwtAgPIo/SAh1a5c6nn2BR6mFNZehTpqKDESzP+fRHVbxwQ==",
"requires": {
"cookie": "0.6.0",
"cookie-signature": "1.0.7",
"debug": "2.6.9",
"depd": "~2.0.0",
"on-headers": "~1.0.2",
"parseurl": "~1.3.3",
"safe-buffer": "5.2.1",
"uid-safe": "~2.1.5"
},
"dependencies": {
"cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="
},
"cookie-signature": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
"integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
}
}
},
"express-slow-down": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/express-slow-down/-/express-slow-down-1.4.0.tgz",
@ -10091,6 +10339,11 @@
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
},
"generic-pool": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g=="
},
"get-assigned-identifiers": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
@ -11387,6 +11640,11 @@
"through2": "^2.0.0"
}
},
"random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@ -11437,6 +11695,19 @@
"picomatch": "^2.2.1"
}
},
"redis": {
"version": "4.6.13",
"resolved": "https://registry.npmjs.org/redis/-/redis-4.6.13.tgz",
"integrity": "sha512-MHgkS4B+sPjCXpf+HfdetBwbRz6vCtsceTmw1pHNYJAsYxrfpOP6dz+piJWGos8wqG7qb3vj/Rrc5qOlmInUuA==",
"requires": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.5.14",
"@redis/graph": "1.1.1",
"@redis/json": "1.0.6",
"@redis/search": "1.1.6",
"@redis/time-series": "1.0.5"
}
},
"regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@ -12068,6 +12339,14 @@
"integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==",
"dev": true
},
"uid-safe": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
"requires": {
"random-bytes": "~1.0.0"
}
},
"unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",

View File

@ -25,11 +25,13 @@
"aws-sdk": "^2.1192.0",
"body-parser": "^1.19.0",
"colors": "^1.4.0",
"connect-redis": "^7.1.1",
"cookie-parser": "^1.4.5",
"crc": "^4.3.2",
"date-fns": "^2.29.3",
"express": "^4.17.1",
"express-rate-limit": "^6.7.0",
"express-session": "^1.18.0",
"fs-extra": "^9.0.1",
"hashmap": "^2.4.0",
"image-pixels": "^1.1.1",
@ -44,6 +46,7 @@
"node-snowflake": "0.0.1",
"pako": "^2.0.2",
"pngjs": "^6.0.0",
"redis": "^4.6.13",
"sharp": "^0.31.3",
"tga": "^1.0.4",
"xml2js": "^0.4.23",

View File

@ -475,6 +475,14 @@ async function getReportsByPost(postID, offset, limit) {
return REPORT.find({ post_id: postID }).sort({created_at: -1}).skip(offset).limit(limit);
}
async function getDuplicateReports(pid, postID) {
verifyConnected();
return REPORT.findOne({
reported_by: pid,
post_id: postID
});
}
async function getReportById(id) {
verifyConnected();
return REPORT.findById(id);
@ -535,5 +543,6 @@ module.exports = {
getAllOpenReports,
getReportsByUser,
getReportsByPost,
getDuplicateReports,
getReportById
};

View File

@ -6,8 +6,16 @@ const util = require('../util');
async function auth(request, response, next) {
// Get pid and fetch user data
request.pid = request.headers['x-nintendo-servicetoken'] ? await util.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
request.user = request.pid ? await util.getUserDataFromPid(request.pid) : null;
if (request.session && request.session.user && request.session.pid && !request.isWrite) {
request.user = request.session.user;
request.pid = request.session.pid;
} else {
request.pid = request.headers['x-nintendo-servicetoken'] ? await util.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
request.user = request.pid ? await util.getUserDataFromPid(request.pid) : null;
request.session.user = request.user;
request.session.pid = request.pid;
}
// Set headers
request.paramPackData = request.headers['x-nintendo-parampack'] ? util.decodeParamPack(request.headers['x-nintendo-parampack']) : null;

View File

@ -10,6 +10,9 @@ async function detectVersion(request, response, next) {
} else {
request.directory = includes(request, 'portal') ? 'portal' : 'ctr';
}
request.isWrite = request.method === 'POST' || request.method === 'PUT' || request.method === 'DELETE';
next();
}

View File

@ -4,24 +4,30 @@ const util = require('../util');
async function webAuth(request, response, next) {
// Get pid and fetch user data
console.time(`Time Request for token ${request.timerDate}`);
try {
request.user = await util.getUserDataFromToken(request.cookies.access_token);
request.pid = request.user.pid;
} catch (e) {
const domain = request.get('host').replace('juxt', '');
response.clearCookie('access_token', {domain: domain, path: '/'});
response.clearCookie('refresh_token', {domain: domain, path: '/'});
response.clearCookie('token_type', {domain: domain, path: '/'});
if (request.path === '/login') {
request.lang = util.processLanguage();
request.token = request.cookies.access_token;
request.paramPackData = null;
return next();
if (request.session && request.session.user && request.session.pid && !request.isWrite) {
request.user = request.session.user;
request.pid = request.session.pid;
} else {
try {
request.user = await util.getUserDataFromToken(request.cookies.access_token);
request.pid = request.user.pid;
request.session.user = request.user;
request.session.pid = request.pid;
} catch (e) {
const domain = request.get('host').replace('juxt', '');
response.clearCookie('access_token', {domain: domain, path: '/'});
response.clearCookie('refresh_token', {domain: domain, path: '/'});
response.clearCookie('token_type', {domain: domain, path: '/'});
if (request.path === '/login') {
request.lang = util.processLanguage();
request.token = request.cookies.access_token;
request.paramPackData = null;
return next();
}
}
}
console.timeEnd(`Time Request for token ${request.timerDate}`);
console.timeEnd(`Time Request ${request.timerDate}`);
request.token = request.cookies.access_token;
@ -54,6 +60,9 @@ function isStartOfPath(path, value) {
return path.indexOf(value) === 0;
}
BigInt.prototype['toJSON'] = function () {
return this.toString();
};
module.exports = webAuth;

51
src/redisCache.js Normal file
View File

@ -0,0 +1,51 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/no-var-requires */
const redis = require('redis');
const logger = require('./logger');
const config = require('../config.json');
const { host, port } = config.redis;
const redisClient = redis.createClient({ host, port });
redisClient.on('error', (error) => {
logger.error(error);
});
redisClient.on('connect', () => {
logger.success('Redis connected');
});
async function setValue(key, value, expireTime) {
if (!redisClient.isOpen) {
return false;
}
await redisClient.set(key, value, 'EX', expireTime);
return true;
}
async function getValue(key) {
if (!redisClient.isOpen) {
return false;
}
const result = await redisClient.get(key);
return result;
}
async function removeValue(key) {
if (!redisClient.isOpen) {
return false;
}
await redisClient.del(key);
return true;
}
module.exports = {
redisClient,
setValue,
getValue,
removeValue
};

View File

@ -1,10 +1,15 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/no-var-requires */
process.title = 'Pretendo - Juxt-Web';
const express = require('express');
const morgan = require('morgan');
const ejs = require('ejs');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const database = require('./database');
const logger = require('./logger');
const { redisClient } = require('./redisCache');
const config = require('../config.json');
const { http: { port } } = config;
@ -32,6 +37,13 @@ app.use(express.urlencoded({
app.use(cookieParser());
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: config.aes_key,
resave: false,
saveUninitialized: false
}));
// import the servers into one
app.use(juxt_web);
@ -63,10 +75,17 @@ app.use((error, request, response) => {
});
// Starts the server
logger.info('Starting server');
async function main() {
// Starts the server
logger.info('Starting server');
await database.connect();
logger.success('Database connected');
await redisClient.connect();
database.connect().then(() => {
app.listen(port, () => {
logger.success(`Server started on port ${port}`);
});
});
}
main().catch(console.error);

View File

@ -8,19 +8,27 @@ const upload = multer({dest: 'uploads/'});
const router = express.Router();
const { POST } = require('../../../../models/post');
const { COMMUNITY } = require('../../../../models/communities');
const redis = require('../../../../redisCache');
router.get('/', async function (req, res) {
const newCommunities = await database.getNewCommunities(6);
const last24Hours = await calculateMostPopularCommunities();
const popularCommunities = await COMMUNITY.aggregate([
{ $match: { olive_community_id: { $in: last24Hours }, parent: null } },
{$addFields: {
index: { $indexOfArray: [ last24Hours, '$olive_community_id' ] }
}},
{ $sort: { index: 1 } },
{ $limit : 9 },
{ $project: { index: 0, _id: 0 } }
]);
const newCommunities = JSON.parse(await redis.getValue('newCommunities')) || await database.getNewCommunities(6);
let popularCommunities = JSON.parse(await redis.getValue('popularCommunities'));
if (!popularCommunities) {
const last24Hours = await calculateMostPopularCommunities();
popularCommunities = await COMMUNITY.aggregate([
{ $match: { olive_community_id: { $in: last24Hours }, parent: null } },
{$addFields: {
index: { $indexOfArray: [ last24Hours, '$olive_community_id' ] }
}},
{ $sort: { index: 1 } },
{ $limit : 9 },
{ $project: { index: 0, _id: 0 } }
]);
redis.setValue('popularCommunities', JSON.stringify(popularCommunities), 60 * 60);
redis.setValue('newCommunities', JSON.stringify(newCommunities), 60 * 60);
}
res.render(req.directory + '/communities.ejs', {
cache: true,
popularCommunities: popularCommunities,
@ -46,9 +54,6 @@ router.get('/all', async function (req, res) {
});
router.get('/:communityID', async function (req, res) {
if (req.params.communityID === '0') {
console.log(req.paramPackData);
}
if (req.query.title_id) {
const community = await database.getCommunityByTitleID(req.query.title_id);
if (!community) {

View File

@ -24,7 +24,7 @@ router.get('/', async function (req, res) {
});
});
router.post('/new', async function (req, res, next) {
router.post('/new', async function (req, res) {
let conversation = await database.getConversationByID(req.body.community_id);
const user2 = await util.getUserDataFromPid(req.body.message_to_pid);
const postID = await generatePostUID(21);
@ -33,7 +33,7 @@ router.post('/new', async function (req, res, next) {
return res.sendStatus(404);
}
if (!conversation) {
if (!user || !user2) {
if (!req.user || !user2) {
return res.sendStatus(422);
}
const document = {
@ -149,8 +149,7 @@ router.post('/new', async function (req, res, next) {
await conversation.newMessage(postPreviewText, user2.pid);
});
router.get('/new/:pid', async function (req, res, next) {
const user = await util.getUserDataFromPid(req.pid);
router.get('/new/:pid', async function (req, res) {
const user2 = await util.getUserDataFromPid(req.params.pid);
const friends = await util.getFriends(user2.pid);
if (!req.user || !user2) {

View File

@ -9,6 +9,7 @@ const rateLimit = require('express-rate-limit');
const {REPORT} = require('../../../../models/report');
const upload = multer({dest: 'uploads/'});
const crypto = require('crypto');
const redis = require('../../../../redisCache');
const router = express.Router();
const postLimit = rateLimit({
@ -99,6 +100,7 @@ router.post('/empathy', yeahLimit, async function (req, res) {
} else {
res.send({status: 423, id: post.id, count: post.empathy_count});
}
await redis.removeValue(`${post.pid}-user_page_posts`);
});
router.post('/new', postLimit, upload.none(), async function (req, res) {
@ -161,6 +163,7 @@ router.delete('/:post_id', async function (req, res) {
} else {
res.send('/users/me');
}
await redis.removeValue(`${post.pid}-user_page_posts`);
});
router.post('/:post_id/new', postLimit, upload.none(), async function (req, res) {
@ -174,6 +177,11 @@ router.post('/:post_id/report', upload.none(), async function (req, res) {
return res.redirect('/404');
}
const duplicate = await database.getDuplicateReports(req.pid, post_id);
if (duplicate) {
return res.redirect(`/posts/${post.id}`);
}
const reportDoc = {
pid: post.pid,
reported_by: req.pid,
@ -292,6 +300,7 @@ async function newPost(req, res) {
}
const newPost = new POST(document);
newPost.save();
await redis.removeValue(`${newPost.pid}-user_page_posts`);
if (parentPost) {
parentPost.reply_count = parentPost.reply_count + 1;
parentPost.save();
@ -303,6 +312,7 @@ async function newPost(req, res) {
user: req.pid,
link: `/posts/${parentPost.id}`
});
await redis.removeValue(`${parentPost.pid}-user_page_posts`);
}
if (parentPost) {
res.redirect('/posts/' + req.params.post_id.toString());

View File

@ -7,6 +7,7 @@ const moment = require('moment');
const upload = multer({ dest: 'uploads/' });
const { POST } = require('../../../../models/post');
const {SETTINGS} = require('../../../../models/settings');
const redis = require('../../../../redisCache');
const router = express.Router();
router.get('/menu', async function (req, res) {
@ -147,8 +148,15 @@ async function userPage(req, res, userID) {
if (isNaN(userID) || !pnid || !userContent) {
return res.redirect('/404');
}
const userSettings = await database.getUserSettings(userID);
const posts = await database.getNumberUserPostsByID(userID, config.post_limit);
let posts = JSON.parse(await redis.getValue(`${userID}-user_page_posts`));
if (!posts) {
posts = await database.getNumberUserPostsByID(userID, config.post_limit);
await redis.setValue(`${userID}-user_page_posts`, JSON.stringify(posts), 60 * 60 * 1);
}
const numPosts = await database.getTotalPostsByUserID(userID);
const communityMap = await util.getCommunityHash();
let friends = [];
@ -171,7 +179,6 @@ async function userPage(req, res, userID) {
mii_image_CDN: config.mii_image_CDN,
link: `/users/${userID}/more?offset=${posts.length}&pjax=true`
};
if (req.query.pjax) {
return res.render(req.directory + '/partials/posts_list.ejs', {
bundle,
@ -180,6 +187,7 @@ async function userPage(req, res, userID) {
});
}
const link = (pnid.pid === req.pid) ? '/users/me/' : `/users/${userID}/`;
res.render(req.directory + '/user_page.ejs', {
template: 'posts_list',
selection: 0,