From de581b74384d53b49f2c6198e1f3890cd85daa6a Mon Sep 17 00:00:00 2001 From: WeiJun0827 <33746295+WeiJun0827@users.noreply.github.com> Date: Fri, 23 Apr 2021 18:02:07 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A8=20Reserve=20user=20register/update?= =?UTF-8?q?=20form-data=20payload=20format=20for=20App=20env=20(#238)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "⏪ Revert removing deprecated register/update avatar APIs and CSRF" This reverts commit 56ef0a32263a494340e9011cebcc315ba3a45dff. * 🔨 Reserve user register/update form-data payload format for App env * 🔥 Remove form-data entry for user update endpoint * 🥅 Add user register content-type error handler * ✅ Add user register content-type test cases * 🩹 Use next rather than throw to emit error * 🩹 Add brackets to improve readability Co-authored-by: William Chong <6198816+williamchong@users.noreply.github.com> Co-authored-by: William Chong <6198816+williamchong@users.noreply.github.com> --- src/routes/users/registerLogin.js | 22 +++++++++++++ test/api/user.test.js | 51 ++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/routes/users/registerLogin.js b/src/routes/users/registerLogin.js index 30e3723e3..d5d1558a9 100644 --- a/src/routes/users/registerLogin.js +++ b/src/routes/users/registerLogin.js @@ -63,8 +63,30 @@ const apiLimiter = new RateLimit({ router.use(loginPlatforms); +function isJson(req) { + return !!req.is('application/json'); +} + +function isApp(req) { + const { 'user-agent': userAgent = '' } = req.headers; + return userAgent.includes('LikeCoinApp'); +} + +function formdataParserForApp(req, res, next) { + if (!isJson(req)) { + if (isApp(req)) { + multer.none()(req, res, next); + } else { + next(new ValidationError('INVALID_CONTENT_TYPE')); + } + } else { + next(); + } +} + router.post( '/new', + formdataParserForApp, apiLimiter, async (req, res, next) => { const { diff --git a/test/api/user.test.js b/test/api/user.test.js index fbfe84efa..505b18b31 100644 --- a/test/api/user.test.js +++ b/test/api/user.test.js @@ -53,7 +53,7 @@ test.serial('USER: Login user. Case: success', async (t) => { t.is(res.status, 200); }); -test.serial('USER: Edit user. Case: success', async (t) => { +test.serial('USER: Edit user by JSON from Web. Case: success', async (t) => { const user = testingUser1; const token = jwtSign({ user }); const payload = { @@ -61,7 +61,7 @@ test.serial('USER: Edit user. Case: success', async (t) => { displayName: testingDisplayName1, ts: Date.now(), wallet: testingWallet1, - email: 'noreply@likecoin.store', + email: testingEmail1, }; const res = await axiosist.post('/api/users/update', payload, { headers: { @@ -72,7 +72,7 @@ test.serial('USER: Edit user. Case: success', async (t) => { t.is(res.status, 200); }); -test.serial('USER: Edit user by form-data. Case: invalid content type', async (t) => { +test.serial('USER: Edit user by form-data from Web. Case: invalid content-type', async (t) => { const user = testingUser1; const token = jwtSign({ user }); const payload = new FormData(); @@ -80,7 +80,7 @@ test.serial('USER: Edit user by form-data. Case: invalid content type', async (t payload.append('displayName', testingDisplayName1); payload.append('ts', Date.now()); payload.append('wallet', testingWallet1); - payload.append('email', 'noreply@likecoin.store'); + payload.append('email', testingEmail1); const res = await axiosist.post('/api/users/update', payload, { headers: { Cookie: `likecoin_auth=${token};`, @@ -151,6 +151,49 @@ test.serial('USER: Verify uuid. Case: success (Need restart server for clean mem t.is(res.data.wallet, testingWallet2); }); +test.serial('USER: Register user by form-data from Web. Case: invalid content-type', async (t) => { + const user = testingUser1; + const token = jwtSign({ user }); + const payload = new FormData(); + payload.append('user', user); + payload.append('displayName', testingDisplayName1); + payload.append('ts', Date.now()); + payload.append('wallet', testingWallet1); + payload.append('email', testingEmail1); + payload.append('platform', 'wallet'); + const res = await axiosist.post('/api/users/new', payload, { + headers: { + Cookie: `likecoin_auth=${token};`, + ...payload.getHeaders(), + }, + }).catch(err => err.response); + + t.is(res.status, 400); + t.is(res.data, 'INVALID_CONTENT_TYPE'); +}); + +test.serial('USER: Register user by form-data from App. Case: invalid platform', async (t) => { + const user = testingUser1; + const token = jwtSign({ user }); + const payload = new FormData(); + payload.append('user', user); + payload.append('displayName', testingDisplayName1); + payload.append('ts', Date.now()); + payload.append('wallet', testingWallet1); + payload.append('email', testingEmail1); + payload.append('platform', 'wallet'); + const res = await axiosist.post('/api/users/new', payload, { + headers: { + Cookie: `likecoin_auth=${token};`, + 'User-Agent': 'LikeCoinApp', + ...payload.getHeaders(), + }, + }).catch(err => err.response); + + t.is(res.status, 400); + t.is(res.data, 'INVALID_PLATFORM'); +}); + // // concurrent cases //