From d11b04efad30c2f5ae3ff3f38ebc1901dbfffd49 Mon Sep 17 00:00:00 2001 From: CaramelKat <32065563+caramelkat@users.noreply.github.com> Date: Wed, 23 Dec 2020 01:37:07 -0600 Subject: [PATCH] The changelog here is too large to put in the commit message, check the updated readme for more information --- README.md | 50 +- package-lock.json | 621 ++++++++++++++++++ package.json | 11 +- src/authentication.js | 204 ++++++ src/config.example.json | 7 +- src/database.js | 26 +- src/models/communities.js | 14 + src/models/post.js | 2 +- src/models/user.js | 158 ++++- src/server.js | 1 + src/services/juxt-web/index.js | 3 + .../juxt-web/routes/ctr/communities.js | 55 +- src/services/juxt-web/routes/ctr/show.js | 85 ++- src/services/juxt-web/routes/ctr/userpage.js | 97 +++ src/services/juxt-web/routes/index.js | 3 + .../juxt-web/routes/portal/communities.js | 60 +- src/services/juxt-web/routes/portal/posts.js | 132 ++++ src/services/juxt-web/routes/portal/show.js | 86 ++- .../juxt-web/routes/portal/userpage.js | 224 +++++++ src/services/juxt-web/routes/portal/web.js | 8 + src/views/ctr_communities.ejs | 141 ++-- src/views/ctr_communities_ajax.ejs | 74 +++ src/views/ctr_guest_notice.ejs | 87 +++ src/views/ctr_user_page_ajax.ejs | 59 ++ src/views/portal_communities.ejs | 32 +- src/views/portal_communities_ajax.ejs | 4 +- src/views/portal_community.ejs | 117 +++- src/views/portal_community_ajax.ejs | 63 +- ...xy_ajax.ejs => portal_community_posts.ejs} | 2 +- src/views/portal_first_run.ejs | 262 ++++++++ src/views/portal_guest_notice.ejs | 104 +++ src/views/portal_me_page.ejs | 258 ++++++++ src/views/portal_me_page_ajax.ejs | 222 +++++++ src/views/portal_me_settings_ajax.ejs | 20 + src/views/portal_post_viewer_ajax.ejs | 65 ++ src/views/portal_show.ejs | 36 +- src/views/portal_user_page.ejs | 196 ++++++ src/views/portal_user_page_ajax.ejs | 160 +++++ src/views/portal_user_page_posts_ajax.ejs | 59 ++ src/webfiles/ctr/css/juxt.css | 123 ++++ src/webfiles/ctr/js/juxt.js | 19 +- src/webfiles/portal/css/juxt.css | 325 ++++++++- src/webfiles/portal/js/juxt.js | 350 ++++++++-- 43 files changed, 4367 insertions(+), 258 deletions(-) create mode 100644 src/authentication.js create mode 100644 src/services/juxt-web/routes/ctr/userpage.js create mode 100644 src/services/juxt-web/routes/portal/posts.js create mode 100644 src/services/juxt-web/routes/portal/userpage.js create mode 100644 src/views/ctr_communities_ajax.ejs create mode 100644 src/views/ctr_guest_notice.ejs create mode 100644 src/views/ctr_user_page_ajax.ejs rename src/views/{portal_community_boxy_ajax.ejs => portal_community_posts.ejs} (97%) create mode 100644 src/views/portal_first_run.ejs create mode 100644 src/views/portal_guest_notice.ejs create mode 100644 src/views/portal_me_page.ejs create mode 100644 src/views/portal_me_page_ajax.ejs create mode 100644 src/views/portal_me_settings_ajax.ejs create mode 100644 src/views/portal_post_viewer_ajax.ejs create mode 100644 src/views/portal_user_page.ejs create mode 100644 src/views/portal_user_page_ajax.ejs create mode 100644 src/views/portal_user_page_posts_ajax.ejs diff --git a/README.md b/README.md index b4a2caf..b46941e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,48 @@ -# juxt-web -Juxtaposition applet UI for the Wii U and 3DS +# Juxt-Web + +

+ + + +

+ +## Pretendo replacement for https://portal.olv.nintendo.net and https://ctr.olv.nintendo.net + +# What is this? +This is the PN miiverse replacement web UI, which works with the 3DS and Wii U Miiverse Applets + + +# Install and usage + +First install [NodeJS](https://nodejs.org) and [MongoDB](https://mongodb.com). Download/clone this repo and run `npm i` to install all dependencies. Edit `example.config.js` to your liking and rename it `config.js`. Run the server via `npm run start`. + +Check out the [Wiki](https://github.com/PretendoNetwork/juxt-web/wiki) for information on how to set up your mongoDB to work with the application + +## What works +- [x] View most types of Miiverse posts + * Text, Painting, Screenshot, Youtube, etc. +- [x] Yeah! Posts +- [x] View Communities +- [x] Follow Communities +- [x] Follow Users +- [x] View User Profiles +- [x] Guest browsing mode +- [x] Full Out-of-box experience +- [x] Authentication with an [account server](https://github.com/PretendoNetwork/account) +- [x] User Bio and privacy settings + +## Currently implemented endpoints + * [GET] /titles/show + * [GET] /communities + * [GET] /communities/[title ID]/new + * [POST] /communities/follow + * [GET] /users/show?pid=[user ID] + * [GET] /users/me + * [POST] /users/follow + * [POST] /post/empathy + +## Footnotes + + * The rules still need to be rewritten, as of now they simply reflect what Nintendo came up with at the time + * This still isn't fully production ready, as it lacks proper error handling in 99% of the client side JS. + * Because of the above, as well as the sheer complexity of patching the applets themselves, I will not be offering support with setting this up for yourself for the time being. Once the documentation is complete in the wiki I'll be happy to help :) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 33c9397..cede224 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,18 @@ "negotiator": "0.6.2" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -59,6 +71,12 @@ "color-convert": "^1.9.0" } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -72,17 +90,49 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -97,6 +147,24 @@ "safe-buffer": "5.1.2" } }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -143,11 +211,59 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==" }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "dev": true, + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -179,12 +295,33 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -225,6 +362,15 @@ "integrity": "sha1-6Z5384LGjy5asrPzqCuAMZV1Kag=", "dev": true }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -233,6 +379,12 @@ "ms": "2.0.0" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, "denque": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", @@ -248,6 +400,52 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "dev": true, + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -331,6 +529,36 @@ "integrity": "sha1-mQ75eUC39MKCPZWTZIt5voWKY4s=", "dev": true }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, "filelist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz", @@ -354,6 +582,23 @@ "unpipe": "~1.0.0" } }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -375,17 +620,48 @@ "universalify": "^1.0.0" } }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -398,6 +674,17 @@ "toidentifier": "1.0.0" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -416,11 +703,32 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, "jake": { "version": "10.8.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", @@ -433,6 +741,25 @@ "minimatch": "^3.0.4" } }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + }, + "dependencies": { + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + } + } + }, "js-yaml": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", @@ -442,6 +769,30 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -458,6 +809,18 @@ } } }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, "kareem": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", @@ -516,6 +879,21 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -620,11 +998,68 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", + "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", + "dev": true, + "requires": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "node-expat": { + "version": "2.3.18", + "resolved": "https://registry.npmjs.org/node-expat/-/node-expat-2.3.18.tgz", + "integrity": "sha512-9dIrDxXePa9HSn+hhlAg1wXkvqOjxefEbMclGxk2cEnq/Y3U7Qo5HNNqeo3fQ4bVmLhcdt3YN1TZy7WMZy4MHw==", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.13.2" + } + }, + "node-rsa": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "requires": { + "asn1": "^0.2.4" + } + }, + "node-snowflake": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-snowflake/-/node-snowflake-0.0.1.tgz", + "integrity": "sha1-C+XqvVsRMfY55j6JxfgtqoFLOrk=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "object-to-xml": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/object-to-xml/-/object-to-xml-2.0.0.tgz", @@ -649,6 +1084,11 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, + "pako": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.2.tgz", + "integrity": "sha512-9e8DRI3+dRLomCmMBAH30B2ejh+blwXr7VmMEx/pVFZlSDA7oyI8uKMhKXr8IrZpoxBF2YlxUvhqRXzTT1i0NA==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -659,6 +1099,17 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pngjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -673,6 +1124,18 @@ "ipaddr.js": "1.9.1" } }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -713,6 +1176,42 @@ "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", @@ -824,11 +1323,34 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "dev": true + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -846,11 +1368,61 @@ "has-flag": "^3.0.0" } }, + "tga": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tga/-/tga-1.0.4.tgz", + "integrity": "sha512-UdYjLm6XDhH0czfel87opaoynxIWI6AXMLkaUvZyl8AzJnAvOH1bHmHjdcolTzi4RjbBU8rgd7ys7sHxFAY1WA==", + "requires": { + "debug": "^2.6.1" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.3.tgz", + "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==", + "dev": true + } + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -860,6 +1432,12 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, "universalify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", @@ -870,6 +1448,15 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -880,11 +1467,39 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "xml2json": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/xml2json/-/xml2json-0.12.0.tgz", + "integrity": "sha512-EPJHRWJnJUYbJlzR4pBhZODwWdi2IaYGtDdteJi0JpZ4OD31IplWALuit8r73dJuM4iHZdDVKY1tLqY2UICejg==", + "dev": true, + "requires": { + "hoek": "^4.2.1", + "joi": "^13.1.2", + "node-expat": "^2.3.18" + } + }, "xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", @@ -901,6 +1516,12 @@ "@types/node": "14.6.2", "js-yaml": "3.14.0" } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true } } } diff --git a/package.json b/package.json index bce3fde..222916d 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "juxt-web", "version": "1.0.0", "dependencies": { + "body-parser": "^1.19.0", "colors": "^1.4.0", "express": "^4.17.1", "fs-extra": "^9.0.1", @@ -9,12 +10,20 @@ "moment": "^2.29.1", "mongoose": "^5.10.14", "morgan": "^1.10.0", + "node-rsa": "^1.1.1", + "node-snowflake": "0.0.1", + "pako": "^2.0.2", + "pngjs": "^6.0.0", + "tga": "^1.0.4", "xmlbuilder": "^15.1.1", "xmlbuilder2": "^2.4.0" }, "devDependencies": { "ejs": "^3.1.5", "express-subdomain": "^1.0.5", - "object-to-xml": "^2.0.0" + "multer": "^1.4.2", + "object-to-xml": "^2.0.0", + "request": "^2.88.2", + "xml2json": "^0.12.0" } } diff --git a/src/authentication.js b/src/authentication.js new file mode 100644 index 0000000..357e7c9 --- /dev/null +++ b/src/authentication.js @@ -0,0 +1,204 @@ +const crypto = require('crypto'); +const NodeRSA = require('node-rsa'); +const fs = require('fs-extra'); +const database = require('./database'); +const config = require('./config.json'); +const xmlParser = require('xml2json'); +const request = require("request"); +const moment = require('moment'); +const { USER } = require('./models/user'); +let TGA = require('tga'); +let pako = require('pako'); +let PNG = require('pngjs').PNG; + +let methods = { + create_user: function(pid, experience, notifications) { + return new Promise(function(resolve, reject) { + console.log('running me'); + database.connect().then(async yeet => { + await request({ + url: "http://" + config.account_server_domain + "/v1/api/miis?pids=" + pid, + headers: { + 'X-Nintendo-Client-ID': config["X-Nintendo-Client-ID"], + 'X-Nintendo-Client-Secret': config["X-Nintendo-Client-Secret"] + } + }, function (error, response, body) { + if (!error && response.statusCode === 200) { + let xml = xmlParser.toJson(body, {object: true}); + //console.log(xml); + //console.log(xml.miis.mii.images.image[0].cached_url); + const newUsr = { + pid: pid, + created_at: moment().format('YYYY-MM-DD HH:mm:SS'), + user_id: xml.miis.mii.user_id, + account_status: 0, + mii: xml.miis.mii.data, + mii_face_url: xml.miis.mii.images.image[0].cached_url, + pfp_uri: "data:image/png;base64,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", + game_skill: experience, + notifications: notifications, + official: false + }; + const newUsrObj = new USER(newUsr); + //console.log(newUsrObj); + newUsrObj.save(); + resolve(newUsr); + } + else + { + console.log('fail'); + reject(); + } + + }); + + }); + }); + }, + processUser: function(pid) { + return new Promise(function(resolve, reject) { + console.log('running me'); + database.connect().then(async yeet => { + let userObject = await database.getUserByPID(pid); + console.log(userObject); + if(userObject != null) + resolve(userObject); + else + { + console.log('else'); + await request({ + url: "http://account.jemverse.xyz/v1/api/miis?pids=" + pid, + headers: { + 'X-Nintendo-Client-ID': 'a2efa818a34fa16b8afbc8a74eba3eda', + 'X-Nintendo-Client-Secret': 'c91cdb5658bd4954ade78533a339cf9a' + } + }, function (error, response, body) { + if (!error && response.statusCode === 200) { + let xml = xmlParser.toJson(body, {object: true}); + const newUsr = { + pid: pid, + created_at: moment().format('YYYY-MM-DD HH:mm:SS'), + user_id: xml.miis.mii.user_id, + account_status: 0, + mii: xml.miis.mii.data, + official: false + }; + const newUsrObj = new USER(newUsr); + console.log(newUsrObj); + newUsrObj.save(); + resolve(newUsr); + } + else + { + console.log('fail'); + reject(); + } + + }); + + } + + }); + }); + }, + decodeParamPack: function (paramPack) { + /* Decode base64 */ + let dec = Buffer.from(paramPack, "base64").toString("ascii"); + /* Remove starting and ending '/', split into array */ + dec = dec.slice(1, -1).split("\\"); + /* Parameters are in the format [name, val, name, val]. Copy into out{}. */ + const out = {}; + for (let i = 0; i < dec.length; i += 2) { + out[dec[i].trim()] = dec[i + 1].trim(); + } + return out; + }, + processServiceToken: function(token) { + try + { + let B64token = Buffer.from(token, 'base64'); + let decryptedToken = this.decryptToken(B64token); + return decryptedToken.readUInt32LE(0x2); + } + catch(e) + { + console.log(e); + console.error("The token was incorrect"); + return null; + } + + }, + decryptToken: function(token) { + + // Access and refresh tokens use a different format since they must be much smaller + // Assume a small length means access or refresh token + if (token.length <= 32) { + const cryptoPath = `${__dirname}/../certs/access`; + const aesKey = Buffer.from(fs.readFileSync(`${cryptoPath}/aes.key`, { encoding: 'utf8' }), 'hex'); + + const iv = Buffer.alloc(16); + + const decipher = crypto.createDecipheriv('aes-128-cbc', aesKey, iv); + + let decryptedBody = decipher.update(token); + decryptedBody = Buffer.concat([decryptedBody, decipher.final()]); + + return decryptedBody; + } + const cryptoPath = `${__dirname}/certs/access`; + + const cryptoOptions = { + private_key: fs.readFileSync(`${cryptoPath}/private.pem`), + hmac_secret: config.account_server_secret + }; + + const privateKey = new NodeRSA(cryptoOptions.private_key, 'pkcs1-private-pem', { + environment: 'browser', + encryptionScheme: { + 'hash': 'sha256', + } + }); + + const cryptoConfig = token.subarray(0, 0x90); + const signature = token.subarray(0x90, 0xA4); + const encryptedBody = token.subarray(0xA4); + + const encryptedAESKey = cryptoConfig.subarray(0, 128); + const iv = cryptoConfig.subarray(128); + + const decryptedAESKey = privateKey.decrypt(encryptedAESKey); + + const decipher = crypto.createDecipheriv('aes-128-cbc', decryptedAESKey, iv); + + let decryptedBody = decipher.update(encryptedBody); + decryptedBody = Buffer.concat([decryptedBody, decipher.final()]); + const hmac = crypto.createHmac('sha1', cryptoOptions.hmac_secret).update(decryptedBody); + const calculatedSignature = hmac.digest(); + if (!calculatedSignature.equals(signature)) { + console.log('Token signature did not match'); + return null; + } + return decryptedBody; + }, + processPainting: function (painting) { + let paintingBuffer = Buffer.from(painting, 'base64'); + let output = ''; + try + { + output = pako.inflate(paintingBuffer); + } + catch (err) + { + console.error(err); + } + let tga = new TGA(Buffer.from(output)); + let png = new PNG({ + width: tga.width, + height: tga.height + }); + png.data = tga.pixels; + let pngBuffer = PNG.sync.write(png); + return `data:image/png;base64,${pngBuffer.toString('base64')}`; + }, +}; +exports.data = methods; \ No newline at end of file diff --git a/src/config.example.json b/src/config.example.json index f985802..43fb27c 100644 --- a/src/config.example.json +++ b/src/config.example.json @@ -2,10 +2,13 @@ "http": { "port": 80 }, - "secret": "[Database Secret Key]", + "account_server_domain": "", + "account_server_secret": "", + "X-Nintendo-Client-ID": "", + "X-Nintendo-Client-Secret": "", "mongoose": { "uri": "mongodb://localhost:27017", - "database": "[Database Name]", + "database": "Miiverse", "options": { "useNewUrlParser": true, "useUnifiedTopology": true diff --git a/src/database.js b/src/database.js index 812825f..322550f 100644 --- a/src/database.js +++ b/src/database.js @@ -75,7 +75,7 @@ async function getCommunityByID(community_id) { }); } -async function getNumberPostsByCommunity(community) { +async function getTotalPostsByCommunity(community) { verifyConnected(); return POST.find({ title_id: community.title_id @@ -92,13 +92,19 @@ async function getPostByID(postID) { async function getPostsByUserID(userID) { verifyConnected(); - return POST.find({ pid: userID }); } -async function getNumberPostsByUserID(userID) { +async function getNumberUserPostsByID(userID, number) { + verifyConnected(); + return POST.find({ + pid: userID + }).sort({ created_at: -1}).limit(number); +} + +async function getTotalPostsByUserID(userID) { verifyConnected(); return POST.find({ pid: userID @@ -133,6 +139,14 @@ async function getNewPostsByCommunity(community, numberOfPosts) { }).sort({ created_at: -1 }).limit(numberOfPosts); } +async function getUserPostsAfterTimestamp(post, numberOfPosts) { + verifyConnected(); + return POST.find({ + pid: post.pid, + created_at: { $lt: post.created_at } + }).limit(numberOfPosts); +} + async function getDiscoveryHosts() { verifyConnected(); return ENDPOINT.findOne({ @@ -162,14 +176,16 @@ module.exports = { getNewCommunities, getCommunityByTitleID, getCommunityByID, - getNumberPostsByCommunity, + getTotalPostsByCommunity, getDiscoveryHosts, getPostsByCommunity, getHotPostsByCommunity, getNewPostsByCommunity, getPostsByCommunityKey, getPostsByUserID, - getNumberPostsByUserID, + getNumberUserPostsByID, + getTotalPostsByUserID, getPostByID, getUserByPID, + getUserPostsAfterTimestamp, }; \ No newline at end of file diff --git a/src/models/communities.js b/src/models/communities.js index 1ec39d9..136a0c4 100644 --- a/src/models/communities.js +++ b/src/models/communities.js @@ -56,6 +56,20 @@ CommunitySchema.methods.downEmpathy = async function() { await this.save(); }; +CommunitySchema.methods.upFollower = async function() { + const followers = this.get('followers'); + this.set('followers', followers + 1); + + await this.save(); +}; + +CommunitySchema.methods.downFollower = async function() { + const followers = this.get('followers'); + this.set('followers', followers - 1); + + await this.save(); +}; + const COMMUNITY = model('COMMUNITY', CommunitySchema); module.exports = { diff --git a/src/models/post.js b/src/models/post.js index bea3bec..65f94de 100644 --- a/src/models/post.js +++ b/src/models/post.js @@ -19,7 +19,7 @@ const PostSchema = new Schema({ }, community_id: String, country_id: Number, - created_at: String, + created_at: Date, feeling_id: Number, id: Number, is_autopost: { diff --git a/src/models/user.js b/src/models/user.js index 5eeac4a..16c3407 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -8,6 +8,7 @@ const UserSchema = new Schema({ country: String, pfp_uri: String, mii: String, + mii_face_url: String, /** * Account Status * 0 - Fine @@ -24,49 +25,65 @@ const UserSchema = new Schema({ type: Boolean, default: false }, - favorite_communities: { - type: [String], - default: undefined - }, profile_comment: { type: String, default: undefined }, - /** - * Game Skill Level - * 1 - Beginner - * 2 - Intermediate - * 3 - Expert - */ game_skill: { type: Number, default: 0 }, - /** - * Profile Visibility settings - * 1 - Everyone - * 2 - Friends Only - * 3 - Private - */ game_skill_visibility: { - type: Number, - default: 1 + type: Boolean, + default: true }, profile_comment_visibility: { - type: Number, - default: 1 + type: Boolean, + default: true }, birthday_visibility: { - type: Number, - default: 3 + type: Boolean, + default: false }, relationship_visibility: { - type: Number, - default: 2 + type: Boolean, + default: false + }, + country_visibility: { + type: Boolean, + default: false }, profile_favorite_community_visibility: { + type: Boolean, + default: true + }, + notifications: { + type: Boolean, + default: false + }, + likes: { + type: [Number], + default: [0] + }, + followed_communities: { + type: [Number], + default: [0] + }, + followed_users: { + type: [Number], + default: [0] + }, + following_users: { + type: [Number], + default: [0] + }, + followers: { type: Number, - default: 1 + default: 0 + }, + following: { + type: Number, + default: 0 } }); @@ -144,6 +161,97 @@ UserSchema.methods.setFavoriteCommunityVisibility = async function(favoriteCommu await this.save(); }; +UserSchema.methods.getCountryVisibility = async function() { + return this.get('country_visibility'); +}; + +UserSchema.methods.setCountryVisibility = async function(countryVisibility) { + this.set('country_visibility', countryVisibility); + await this.save(); +}; + +UserSchema.methods.addToLikes = async function(postID) { + const likes = this.get('likes'); + likes.addToSet(postID); + await this.save(); +} + +UserSchema.methods.removeFromLike = async function(postID) { + const likes = this.get('likes'); + likes.pull(postID); + await this.save(); +} + +UserSchema.methods.addToCommunities = async function(postID) { + const communities = this.get('followed_communities'); + communities.addToSet(postID); + await this.upFollowing(); + await this.save(); +} + +UserSchema.methods.removeFromCommunities = async function(postID) { + const communities = this.get('followed_communities'); + communities.pull(postID); + await this.downFollowing(); + await this.save(); +} + +UserSchema.methods.addToUsers = async function(postID) { + const users = this.get('followed_users'); + users.addToSet(postID); + await this.upFollowing(); + await this.save(); +} + +UserSchema.methods.removeFromUsers = async function(postID) { + const users = this.get('followed_users'); + users.pull(postID); + await this.downFollowing(); + await this.save(); +} + +UserSchema.methods.addToFollowers = async function(postID) { + const users = this.get('following_users'); + users.addToSet(postID); + await this.upFollower(); + await this.save(); +} + +UserSchema.methods.removeFromFollowers = async function(postID) { + const users = this.get('following_users'); + users.pull(postID); + await this.downFollower(); + await this.save(); +} + +UserSchema.methods.upFollower = async function() { + const followers = this.get('followers'); + this.set('followers', followers + 1); + + await this.save(); +}; + +UserSchema.methods.downFollower = async function() { + const followers = this.get('followers'); + this.set('followers', followers - 1); + + await this.save(); +}; + +UserSchema.methods.upFollowing = async function() { + const following = this.get('following'); + this.set('following', following + 1); + + await this.save(); +}; + +UserSchema.methods.downFollowing = async function() { + const following = this.get('following'); + this.set('following', following - 1); + + await this.save(); +}; + const USER = model('USER', UserSchema); module.exports = { diff --git a/src/server.js b/src/server.js index 3a65a83..54aa202 100644 --- a/src/server.js +++ b/src/server.js @@ -29,6 +29,7 @@ app.use(express.urlencoded({ })); app.use(xmlparser); + // import the servers into one app.use(juxt_web); diff --git a/src/services/juxt-web/index.js b/src/services/juxt-web/index.js index 30449bc..9ee382a 100644 --- a/src/services/juxt-web/index.js +++ b/src/services/juxt-web/index.js @@ -18,10 +18,13 @@ router.use(subdomain('ctr.olv', ctr)); // Setup routes portal.use('/titles/show', routes.PORTAL_SHOW); portal.use('/communities', routes.PORTAL_COMMUNITIES); +portal.use('/users', routes.PORTAL_USER); +portal.use('/post', routes.PORTAL_POST); portal.use('/', routes.PORTAL_WEB); ctr.use('/titles/show', routes.CTR_SHOW); ctr.use('/communities', routes.CTR_COMMUNITIES); +ctr.use('/users', routes.CTR_USER); ctr.use('/', routes.CTR_WEB); module.exports = router; \ No newline at end of file diff --git a/src/services/juxt-web/routes/ctr/communities.js b/src/services/juxt-web/routes/ctr/communities.js index 802f3a4..54e3014 100644 --- a/src/services/juxt-web/routes/ctr/communities.js +++ b/src/services/juxt-web/routes/ctr/communities.js @@ -8,14 +8,25 @@ var router = express.Router(); /* GET discovery server. */ router.get('/', function (req, res) { res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') database.connect().then(async e => { - let popularCommunities = await database.getMostPopularCommunities(9); - let newCommunities = await database.getNewCommunities(6); - res.render('ctr_communities.ejs', { - // EJS variable and server-side variable - popularCommunities: popularCommunities, - newCommunities: newCommunities - }); + let popularCommunities = await database.getMostPopularCommunities(6); + let newCommunities = await database.getNewCommunities(3); + if(isAJAX) { + res.render('ctr_communities_ajax.ejs', { + // EJS variable and server-side variable + popularCommunities: popularCommunities, + newCommunities: newCommunities + }); + } + else { + res.render('ctr_communities.ejs', { + // EJS variable and server-side variable + popularCommunities: popularCommunities, + newCommunities: newCommunities + }); + } + }).catch(error => { res.set("Content-Type", "application/xml"); res.statusCode = 400; @@ -35,15 +46,31 @@ router.get('/', function (req, res) { router.get('/*/new', function (req, res) { res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); let community_id = req.originalUrl.replace('/communities/', '').replace('/new','').trim(); + var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') + if(isAJAX) + community_id = community_id.substring(0, community_id.indexOf('?')); database.connect().then(async e => { - let community = await database.getCommunityByID(community_id); - let newPosts = await database.getPostsByCommunity(community, 25); - res.render('ctr_community.ejs', { - // EJS variable and server-side variable - community: community, - newPosts: newPosts - }); + let community = await database.getCommunityByID(community_id.substring(0, community_id)); + let newPosts = await database.getNewPostsByCommunity(community, 100); + let totalNumPosts = await database.getNumberPostsByCommunity(community); + if(isAJAX) { + res.render('ctr_community_ajax.ejs', { + // EJS variable and server-side variable + community: community, + newPosts: newPosts, + totalNumPosts: totalNumPosts + }); + } + else { + res.render('ctr_community.ejs', { + // EJS variable and server-side variable + community: community, + newPosts: newPosts, + totalNumPosts: totalNumPosts + }); + } }).catch(error => { + console.error(error); res.set("Content-Type", "application/xml"); res.statusCode = 400; response = { diff --git a/src/services/juxt-web/routes/ctr/show.js b/src/services/juxt-web/routes/ctr/show.js index e5fbbf6..4559c30 100644 --- a/src/services/juxt-web/routes/ctr/show.js +++ b/src/services/juxt-web/routes/ctr/show.js @@ -1,7 +1,7 @@ var express = require('express'); var xml = require('object-to-xml'); const database = require('../../../../database'); -//const util = require('../../../../util/authentication'); +const util = require('../../../../authentication'); const ejs = require('ejs'); var router = express.Router(); @@ -9,14 +9,83 @@ var router = express.Router(); router.get('/', function (req, res) { res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); database.connect().then(async e => { - let popularCommunities = await database.getMostPopularCommunities(9); - let newCommunities = await database.getNewCommunities(6); - res.render('ctr_show.ejs', { - // EJS variable and server-side variable - popularCommunities: popularCommunities, - newCommunities: newCommunities - }); + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let user = null; + if(pid === null) + { + pid = 1000000000; + user = await database.getUserByPID(pid); + let popularCommunities = await database.getMostPopularCommunities(9); + let newCommunities = await database.getNewCommunities(6); + res.render('ctr_guest_notice.ejs', {}); + } + else + { + user = await database.getUserByPID(pid); + if(user === null) + { + res.render('ctr_first_run.ejs', {}); + } + else + { + let popularCommunities = await database.getMostPopularCommunities(9); + let newCommunities = await database.getNewCommunities(6); + res.render('ctr_show.ejs', { + // EJS variable and server-side variable + popularCommunities: popularCommunities, + newCommunities: newCommunities + }); + } + } }).catch(error => { + console.log(error) + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.get('/first', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + res.render('ctr_first_run.ejs', {}); +}); + +router.post('/newUser', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let user = null; + if(pid === null) + { + res.sendStatus(501); + } + else + { + user = await database.getUserByPID(pid); + if(user === null) + { + await util.data.create_user(pid, req.body.experience, req.body.notifications); + if(await database.getUserByPID(pid) !== null) + res.sendStatus(200); + else + res.sendStatus(504); + } + else + { + res.sendStatus(504); + } + } + }).catch(error => { + console.log(error) res.set("Content-Type", "application/xml"); res.statusCode = 400; response = { diff --git a/src/services/juxt-web/routes/ctr/userpage.js b/src/services/juxt-web/routes/ctr/userpage.js new file mode 100644 index 0000000..7da82a4 --- /dev/null +++ b/src/services/juxt-web/routes/ctr/userpage.js @@ -0,0 +1,97 @@ +var express = require('express'); +var xml = require('object-to-xml'); +const database = require('../../../../database'); +const util = require('../../../../authentication'); +const ejs = require('ejs'); +var router = express.Router(); + +/* GET discovery server. */ +router.get('/me', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') + database.connect().then(async e => { + + //let paramPackData = util.data.decodeParamPack(req.headers["x-nintendo-parampack"]); + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + //console.log(req.headers["x-nintendo-servicetoken"]); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + let newPosts = await database.getPostsByUserID(pid); + let numPosts = await database.getNumberPostsByUserID(pid); + if(isAJAX) { + res.render('ctr_user_page_ajax.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + else { + res.render('portal_user_page.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.get('/show', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') + var userID = req.query.pid; + database.connect().then(async e => { + let user = await database.getUserByPID(userID); + let newPosts = await database.getPostsByUserID(user.pid); + let numPosts = await database.getNumberPostsByUserID(user.pid); + if(isAJAX) { + res.render('portal_user_page_ajax.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + else { + res.render('portal_user_page.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + }).catch(error => { + console.error(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +module.exports = router; diff --git a/src/services/juxt-web/routes/index.js b/src/services/juxt-web/routes/index.js index 597e75e..cdae624 100644 --- a/src/services/juxt-web/routes/index.js +++ b/src/services/juxt-web/routes/index.js @@ -2,7 +2,10 @@ module.exports = { PORTAL_SHOW: require('./portal/show'), PORTAL_WEB: require('./portal/web'), PORTAL_COMMUNITIES: require('./portal/communities'), + PORTAL_USER: require('./portal/userpage'), + PORTAL_POST: require('./portal/posts'), CTR_SHOW: require('./ctr/show'), CTR_WEB: require('./ctr/web'), CTR_COMMUNITIES: require('./ctr/communities'), + CTR_USER: require('./ctr/userpage'), }; \ No newline at end of file diff --git a/src/services/juxt-web/routes/portal/communities.js b/src/services/juxt-web/routes/portal/communities.js index cca4548..749ceb9 100644 --- a/src/services/juxt-web/routes/portal/communities.js +++ b/src/services/juxt-web/routes/portal/communities.js @@ -1,13 +1,14 @@ var express = require('express'); var xml = require('object-to-xml'); const database = require('../../../../database'); -//const util = require('../../../../util/authentication'); +const util = require('../../../../authentication'); const ejs = require('ejs'); +var multer = require('multer'); +var upload = multer({ dest: 'uploads/' }); var router = express.Router(); -/* GET discovery server. */ router.get('/', function (req, res) { - res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2'); var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') database.connect().then(async e => { let popularCommunities = await database.getMostPopularCommunities(9); @@ -44,21 +45,26 @@ router.get('/', function (req, res) { }); router.get('/*/new', function (req, res) { - res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2'); let community_id = req.originalUrl.replace('/communities/', '').replace('/new','').trim(); var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') if(isAJAX) community_id = community_id.substring(0, community_id.indexOf('?')); database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); let community = await database.getCommunityByID(community_id.substring(0, community_id)); let newPosts = await database.getNewPostsByCommunity(community, 100); - let totalNumPosts = await database.getNumberPostsByCommunity(community); + let totalNumPosts = await database.getTotalPostsByCommunity(community); if(isAJAX) { res.render('portal_community_ajax.ejs', { // EJS variable and server-side variable community: community, newPosts: newPosts, - totalNumPosts: totalNumPosts + totalNumPosts: totalNumPosts, + user: user }); } else { @@ -66,7 +72,8 @@ router.get('/*/new', function (req, res) { // EJS variable and server-side variable community: community, newPosts: newPosts, - totalNumPosts: totalNumPosts + totalNumPosts: totalNumPosts, + user: user }); } }).catch(error => { @@ -86,4 +93,43 @@ router.get('/*/new', function (req, res) { }); }); +router.post('/follow', upload.none(), function (req, res) { + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let community = await database.getCommunityByID(req.body.communityID); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + if(req.body.type === 'true' && user !== null && user.followed_communities.indexOf(community.id) === -1) + { + community.upFollower(); + user.addToCommunities(community.id); + res.sendStatus(200); + } + else if(req.body.type === 'false' && user !== null && user.followed_communities.indexOf(community.id) !== -1) + { + community.downFollower(); + user.removeFromCommunities(community.id); + res.sendStatus(200); + } + else + res.sendStatus(423); + + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 423; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + module.exports = router; diff --git a/src/services/juxt-web/routes/portal/posts.js b/src/services/juxt-web/routes/portal/posts.js new file mode 100644 index 0000000..c73940a --- /dev/null +++ b/src/services/juxt-web/routes/portal/posts.js @@ -0,0 +1,132 @@ +var express = require('express'); +var xml = require('object-to-xml'); +const database = require('../../../../database'); +const util = require('../../../../authentication'); +const { POST } = require('../../../../models/post'); +const ejs = require('ejs'); +var multer = require('multer'); +var upload = multer({ dest: 'uploads/' }); +const snowflake = require('node-snowflake').Snowflake; +const moment = require('moment'); +var router = express.Router(); + +router.post('/empathy', function (req, res) { + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let post = await database.getPostByID(req.body.postID); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + if(req.body.type === 'up' && user !== null && user.likes.indexOf(post.id) === -1 && user.id !== post.pid) + { + post.upEmpathy(); + user.addToLikes(post.id) + res.sendStatus(200); + } + else if(req.body.type === 'down' && user !== null && user.likes.indexOf(post.id) !== -1 && user.id !== post.pid) + { + post.downEmpathy(); + user.removeFromLike(post.id); + res.sendStatus(200); + } + else + res.sendStatus(423); + + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 423; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.post('/new', upload.none(), async function (req, res, next) { + try + { + let paramPackData = util.data.decodeParamPack(req.headers["x-nintendo-parampack"]); + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + //console.log(pid); + if(pid === null) + { + throw new Error('The User token was not valid'); + } + else + { + let usrObj = await database.getUserByPID(pid); + const creationDate = moment().format('YYYY-MM-DD HH:MM:SS'); + let appData = ""; + if (req.body.app_data) { + appData = req.body.app_data.replace(/\0/g, "").trim(); + } + let painting = ""; + if (req.body.painting) { + painting = req.body.painting.replace(/\0/g, "").trim(); + } + let paintingURI = ""; + if (req.body.painting) { + paintingURI = await util.data.processPainting(painting); + } + let screenshot = ""; + if (req.body.screenshot) { + screenshot = req.body.screenshot.replace(/\0/g, "").trim(); + } + const document = { + title_id: paramPackData.title_id, + screen_name: usrObj.user_id, + body: req.body.body, + app_data: appData, + painting: painting, + painting_uri: paintingURI, + screenshot: screenshot, + url: req.body.url, + search_key: req.body.search_key, + topic_tag: req.body.topic_tag, + community_id: req.body.community_id, + country_id: paramPackData.country_id, + created_at: creationDate, + feeling_id: req.body.feeling_id, + id: snowflake.nextId(), + is_autopost: req.body.is_autopost, + is_spoiler: req.body.is_spoiler, + is_app_jumpable: req.body.is_app_jumpable, + language_id: req.body.language_id, + mii: usrObj.mii, + mii_face_url: usrObj.pfp_uri, + pid: pid, + platform_id: paramPackData.platform_id, + region_id: paramPackData.region_id, + }; + const newPost = new POST(document); + newPost.save(); + res.sendStatus(200); + } + } + catch (e) + { + console.error(e); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 7, + message: "POSTING_FROM_NNID" + } + }; + res.send("\n" + xml(response)); + } + +}); + +module.exports = router; diff --git a/src/services/juxt-web/routes/portal/show.js b/src/services/juxt-web/routes/portal/show.js index 4d3dfd0..ea8a4bb 100644 --- a/src/services/juxt-web/routes/portal/show.js +++ b/src/services/juxt-web/routes/portal/show.js @@ -1,22 +1,90 @@ var express = require('express'); var xml = require('object-to-xml'); const database = require('../../../../database'); -//const util = require('../../../../util/authentication'); +const util = require('../../../../authentication'); const ejs = require('ejs'); var router = express.Router(); /* GET discovery server. */ router.get('/', function (req, res) { - res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2'); database.connect().then(async e => { - let popularCommunities = await database.getMostPopularCommunities(9); - let newCommunities = await database.getNewCommunities(6); - res.render('portal_show.ejs', { - // EJS variable and server-side variable - popularCommunities: popularCommunities, - newCommunities: newCommunities - }); + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let user = null; + if(pid === null) + { + pid = 1000000000; + user = await database.getUserByPID(pid); + let popularCommunities = await database.getMostPopularCommunities(9); + let newCommunities = await database.getNewCommunities(6); + res.render('portal_guest_notice.ejs', {}); + } + else + { + user = await database.getUserByPID(pid); + if(user === null) + { + res.render('portal_first_run.ejs', {}); + } + else + { + let popularCommunities = await database.getMostPopularCommunities(9); + let newCommunities = await database.getNewCommunities(6); + res.render('portal_show.ejs', { + // EJS variable and server-side variable + popularCommunities: popularCommunities, + newCommunities: newCommunities + }); + } + } }).catch(error => { + console.log(error) + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.get('/first', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2'); + res.render('portal_first_run.ejs', {}); +}); + +router.post('/newUser', function (req, res) { + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let user = null; + if(pid === null) + { + res.sendStatus(501); + } + else + { + user = await database.getUserByPID(pid); + if(user === null) + { + await util.data.create_user(pid, req.body.experience, req.body.notifications); + if(await database.getUserByPID(pid) !== null) + res.sendStatus(200); + else + res.sendStatus(504); + } + else + { + res.sendStatus(504); + } + } + }).catch(error => { + console.log(error) res.set("Content-Type", "application/xml"); res.statusCode = 400; response = { diff --git a/src/services/juxt-web/routes/portal/userpage.js b/src/services/juxt-web/routes/portal/userpage.js new file mode 100644 index 0000000..99c497f --- /dev/null +++ b/src/services/juxt-web/routes/portal/userpage.js @@ -0,0 +1,224 @@ +var express = require('express'); +var xml = require('object-to-xml'); +const database = require('../../../../database'); +const util = require('../../../../authentication'); +const ejs = require('ejs'); +var multer = require('multer'); +var upload = multer({ dest: 'uploads/' }); +var router = express.Router(); + +router.get('/me', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2||fonts.googleapis.com,,2'); + var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') + database.connect().then(async e => { + + //let paramPackData = util.data.decodeParamPack(req.headers["x-nintendo-parampack"]); + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + let newPosts = await database.getNumberUserPostsByID(pid, 1); + let numPosts = await database.getTotalPostsByUserID(pid); + if(isAJAX) { + res.render('portal_me_page_ajax.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + else { + res.render('portal_me_page.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.post('/me', upload.none(), function (req, res) { + console.log('yeet im running look at me you dumb bitch'); + database.connect().then(async e => { + + //let paramPackData = util.data.decodeParamPack(req.headers["x-nintendo-parampack"]); + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + if (pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + + user.country_visibility = !!req.body.country; + + user.birthday_visibility = !!req.body.birthday; + + user.game_skill_visibility = !!req.body.experience; + + user.profile_comment_visibility = !!req.body.commentShow; + + if (req.body.comment) + user.setProfileComment(req.body.comment); + + res.redirect('/users/me'); + + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + }) +}); + +router.get('/show', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2'); + var isAJAX = ((req.query.ajax+'').toLowerCase() === 'true') + var userID = req.query.pid; + if(userID === 'me') { + res.sendStatus(504); + return; + } + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + if(pid === null) + pid = 1000000000; + let parentUser = await database.getUserByPID(pid); + + let user = await database.getUserByPID(userID); + let newPosts = await database.getNumberUserPostsByID(user.pid, 1); + let numPosts = await database.getTotalPostsByUserID(user.pid); + if(isAJAX) { + res.render('portal_user_page_ajax.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts, + parentUser: parentUser + }); + } + else { + res.render('portal_user_page.ejs', { + // EJS variable and server-side variable + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + }).catch(error => { + console.error(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.get('/loadPosts', function (req, res) { + res.header('X-Nintendo-WhiteList','1|http,youtube.com,,2|https,youtube.com,,2|http,.youtube.com,,2|https,.youtube.com,,2|http,.ytimg.com,,2|https,.ytimg.com,,2|http,.googlevideo.com,,2|https,.googlevideo.com,,2|https,youtube.com,/embed/,6|https,youtube.com,/e/,6|https,youtube.com,/v/,6|https,www.youtube.com,/embed/,6|https,www.youtube.com,/e/,6|https,www.youtube.com,/v/,6|https,youtube.googleapis.com,/e/,6|https,youtube.googleapis.com,/v/,6|http,maps.googleapis.com,/maps/api/streetview,2|https,maps.googleapis.com,/maps/api/streetview,2|http,cbk0.google.com,/cbk,2|https,cbk0.google.com,/cbk,2|http,cbk1.google.com,/cbk,2|https,cbk1.google.com,/cbk,2|http,cbk2.google.com,/cbk,2|https,cbk2.google.com,/cbk,2|http,cbk3.google.com,/cbk,2|https,cbk3.google.com,/cbk,2|https,.cloudfront.net,,2|https,www.google-analytics.com,/,2|https,stats.g.doubleclick.net,,2|https,www.google.com,/ads/,2|https,ssl.google-analytics.com,,2|http,fonts.googleapis.com,,2|fonts.googleapis.com,,2|https,www.googletagmanager.com,,2'); + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let post = await database.getPostByID(req.query.postID); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + let newPosts = await database.getUserPostsAfterTimestamp(post, 1); + let numPosts = await database.getNumberUserPostsByID(pid); + if(newPosts.length > 0) + { + res.render('portal_user_page_posts_ajax.ejs', { + user: user, + newPosts: newPosts, + numPosts: numPosts + }); + } + else + { + res.sendStatus(204); + } + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 400; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +router.post('/follow', upload.none(), function (req, res) { + database.connect().then(async e => { + let pid = util.data.processServiceToken(req.headers["x-nintendo-servicetoken"]); + let userToFollow = await database.getUserByPID(req.body.userID); + if(pid === null) + pid = 1000000000; + let user = await database.getUserByPID(pid); + if(req.body.type === 'true' && user !== null && user.followed_users.indexOf(userToFollow.pid) === -1) + { + userToFollow.addToFollowers(user.pid); + user.addToUsers(userToFollow.pid); + res.sendStatus(200); + } + else if(req.body.type === 'false' && user !== null && user.followed_users.indexOf(userToFollow.pid) !== -1) + { + userToFollow.removeFromFollowers(user.pid); + user.removeFromUsers(userToFollow.pid); + res.sendStatus(200); + } + else + res.sendStatus(423); + + }).catch(error => { + console.log(error); + res.set("Content-Type", "application/xml"); + res.statusCode = 423; + response = { + result: { + has_error: 1, + version: 1, + code: 400, + error_code: 15, + message: "SERVER_ERROR" + } + }; + res.send("\n" + xml(response)); + }); +}); + +module.exports = router; diff --git a/src/services/juxt-web/routes/portal/web.js b/src/services/juxt-web/routes/portal/web.js index 153449e..0b48d10 100644 --- a/src/services/juxt-web/routes/portal/web.js +++ b/src/services/juxt-web/routes/portal/web.js @@ -19,4 +19,12 @@ router.get('/icons/mario-kart.jpg', function (req, res) { res.sendFile('icons/mario-kart.jpg', {root: path.join(__dirname, '../../../../webfiles/portal/')}); }); +router.get('/fonts/Poppins-Light.woff', function (req, res) { + res.sendFile('fonts/Poppins-Light.woff', {root: path.join(__dirname, '../../../../webfiles/portal/')}); +}); + +router.get('/fonts/Poppins-Light.ttf', function (req, res) { + res.sendFile('fonts/Poppins-Light.ttf', {root: path.join(__dirname, '../../../../webfiles/portal/')}); +}); + module.exports = router; diff --git a/src/views/ctr_communities.ejs b/src/views/ctr_communities.ejs index 45125af..ac1ab72 100644 --- a/src/views/ctr_communities.ejs +++ b/src/views/ctr_communities.ejs @@ -1,74 +1,89 @@ -
-
-

- Check out the communities for the games that you play or games that you're curious about! -

+ + + + + 3DS Testing + + + + + +
+
+
+

+ Check out the communities for the games that you play or games that you're curious about! +

+
+
+

Communities

-
-

Communities

-
-
-
-
- -
- +
+

New Communities

+ + + <% for(var j = 0; j < newCommunities.length; j++) {%> + <% if(j === newCommunities.length - 1) { %> + + + + <% } else { %> + + + + <% }} %> + +
+
+ +

<%= newCommunities[j].name %>

+

<%= newCommunities[j].followers %> followers

+
+
+
+ +

<%= newCommunities[j].name %>

+

<%= newCommunities[j].followers %> followers

+
+
+
+
-
-

New Communities

- - - <% for(var j = 0; j < newCommunities.length; j++) {%> - <% if(j === newCommunities.length - 1) { %> - - - - <% } else { %> - - - - <% }} %> - -
-
- -

<%= newCommunities[j].name %>

-

<%= newCommunities[j].followers %> followers

-
-
-
- -

<%= newCommunities[j].name %>

-

<%= newCommunities[j].followers %> followers

-
-
-
-
-
\ No newline at end of file +
+ + + \ No newline at end of file diff --git a/src/views/ctr_communities_ajax.ejs b/src/views/ctr_communities_ajax.ejs new file mode 100644 index 0000000..d41c131 --- /dev/null +++ b/src/views/ctr_communities_ajax.ejs @@ -0,0 +1,74 @@ +
+
+

+ Check out the communities for the games that you play or games that you're curious about! +

+
+
+

Communities

+
+
+
+
+ +
+ +
+

New Communities

+ + + <% for(var j = 0; j < newCommunities.length; j++) {%> + <% if(j === newCommunities.length - 1) { %> + + + + <% } else { %> + + + + <% }} %> + +
+
+ +

<%= newCommunities[j].name %>

+

<%= newCommunities[j].followers %> followers

+
+
+
+ +

<%= newCommunities[j].name %>

+

<%= newCommunities[j].followers %> followers

+
+
+
+
+
\ No newline at end of file diff --git a/src/views/ctr_guest_notice.ejs b/src/views/ctr_guest_notice.ejs new file mode 100644 index 0000000..06a009c --- /dev/null +++ b/src/views/ctr_guest_notice.ejs @@ -0,0 +1,87 @@ + + + + + + + + +
+

Welcome to Juxtaposition!

+
+

+ Juxt is a gaming community that connects people from all over the world using Mii characters. + Use Juxt to share your gaming experiences and meet people from around the world. +

+
+ + +
+ + + + + + \ No newline at end of file diff --git a/src/views/ctr_user_page_ajax.ejs b/src/views/ctr_user_page_ajax.ejs new file mode 100644 index 0000000..33c7198 --- /dev/null +++ b/src/views/ctr_user_page_ajax.ejs @@ -0,0 +1,59 @@ +
+
+

+ +

+
+
+

<%= user.user_id %>

+
+
+ + + + + + + + + + +
+
+

Country

+

N/A

+
+
+
+

Birthday

+

N/A

+
+
+
+

Game experience

+

+ <%if(user.game_skill === 0) {%> + Beginner + <%} else if(user.game_skill === 1) {%> + Intermediate + <%} else if(user.game_skill === 2) {%> + Expert + <%} else {%> + N/A + <%}%> +

+
+
+
+

Yeahs

+

N/A

+
+
+ +
+

New Communities

+
+
+
\ No newline at end of file diff --git a/src/views/portal_communities.ejs b/src/views/portal_communities.ejs index 78a2d69..b13db40 100644 --- a/src/views/portal_communities.ejs +++ b/src/views/portal_communities.ejs @@ -2,25 +2,41 @@ + + + + + - - - - - + + + + + -

Communities

-
+ +
+
-
+
+
+
+ + New Post +
+
-
+ <%if(user.followed_communities.indexOf(community.id) !== -1){ %> +
+

Following

+
+ <%} else {%> +
+

Follow Community

+
+ <%}%>

<%= community.name %>

<%= community.description %>

@@ -67,16 +160,16 @@ <% newPosts.forEach(function(post) { %>
<%if(post.verified) {%> - + <%} else {%> - + <%}%> -

<%= post.screen_name %>

+

<%= post.screen_name %>

<%= post.created_at %>

-
+
<%= post.empathy_count %> Yeahs
diff --git a/src/views/portal_community_ajax.ejs b/src/views/portal_community_ajax.ejs index 04be89a..68b9273 100644 --- a/src/views/portal_community_ajax.ejs +++ b/src/views/portal_community_ajax.ejs @@ -1,8 +1,59 @@ +
+
+
+ +
+ + + + + + + +
+ + + + + + + + +
+

Post to <%= community.name %>

+
+
T
+
+ +
+
P
+
+
+
+ +
+
+
+
+
-
+
+
+
+ + New Post +
+
-
+ <%if(user.followed_communities.indexOf(community.id) !== -1){ %> +
+

Following

+
+ <%} else {%> +
+

Follow Community

+
+ <%}%>

<%= community.name %>

<%= community.description %>

@@ -51,16 +102,16 @@ <% newPosts.forEach(function(post) { %>