From 2b9cae2ca2d53eb07b7479ea801f7b4fee774800 Mon Sep 17 00:00:00 2001 From: HF Date: Wed, 17 Mar 2021 02:24:30 +0100 Subject: [PATCH] move all fetch requets from components to actions/fetch --- src/actions/fetch.js | 280 +++++++++++++++++++---------- src/components/ChangeMail.jsx | 22 +-- src/components/ChangeName.jsx | 21 +-- src/components/ChangePassword.jsx | 23 +-- src/components/DeleteAccount.jsx | 21 +-- src/components/HelpModal.jsx | 5 - src/components/LogInForm.jsx | 21 +-- src/components/NewPasswordForm.jsx | 20 +-- src/components/SignUpForm.jsx | 24 +-- src/components/UserMessages.jsx | 17 +- src/utils/validation.js | 20 --- 11 files changed, 210 insertions(+), 264 deletions(-) diff --git a/src/actions/fetch.js b/src/actions/fetch.js index b12274e..f42ea3a 100644 --- a/src/actions/fetch.js +++ b/src/actions/fetch.js @@ -1,11 +1,11 @@ /* * Collect api fetch commands for actions here * (chunk and tiles requests in ui/ChunkLoader*.js) - * (user settings requests in their components) * * @flow */ +import { t } from 'ttag'; /* * Adds customizeable timeout to fetch @@ -27,123 +27,213 @@ async function fetchWithTimeout(resource, options) { } /* - * block / unblock user - * userId id of user to block - * block true if block, false if unblock - * return error string or null if successful + * Parse response from API + * @param response + * @return Object of response */ -export async function requestBlock(userId: number, block: boolean) { - const response = await fetchWithTimeout('api/block', { - method: 'POST', - credentials: 'include', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - userId, - block, - }), - }); +async function parseAPIresponse(response) { + if (!response.ok) { + const code = response.status; + return { + errors: [t`Connection error ${code} :(`], + }; + } try { - const res = await response.json(); - if (res.errors) { - return res.errors[0]; - } - if (response.ok && res.status === 'ok') { - return null; - } - return 'Unknown Error'; - } catch { - return 'Connection Error'; + return await response.json(); + } catch (e) { + return { + errors: [t`Server answered with gibberish :(`], + }; } } +/* + * Make API POST Request + * @param url URL of post api endpoint + * @param body Body of request + * @return Object with response or error Array + */ +async function makeAPIPOSTRequest(url, body) { + try { + const response = await fetchWithTimeout(url, { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }); + + return parseAPIresponse(response); + } catch (e) { + return { + errors: [t`Could not connect to server, please try again later :(`], + }; + } +} + +/* + * Make API GET Request + * @param url URL of get api endpoint + * @return Object with response or error Array + */ +async function makeAPIGETRequest(url) { + try { + const response = await fetchWithTimeout(url, { + credentials: 'include', + }); + + return parseAPIresponse(response); + } catch (e) { + return { + errors: [t`Could not connect to server, please try again later :(`], + }; + } +} + +/* + * block / unblock user + * @param userId id of user to block + * @param block true if block, false if unblock + * @return error string or null if successful + */ +export async function requestBlock(userId: number, block: boolean) { + const res = await makeAPIPOSTRequest( + 'api/block', + { userId, block }, + ); + if (res.errors) { + return res.errors[0]; + } + if (res.status === 'ok') { + return null; + } + return t`Unknown Error`; +} + /* * start new DM channel with user - * query Object with either userId: number or userName: string - * return channel Array on success, error string if not + * @param query Object with either userId: number or userName: string + * @return channel Array on success, error string if not */ export async function requestStartDm(query) { - const response = await fetchWithTimeout('api/startdm', { - method: 'POST', - credentials: 'include', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(query), - }); - - try { - const res = await response.json(); - if (res.errors) { - return res.errors[0]; - } - if (response.ok && res.channel) { - const { channel } = res; - return channel; - } - - return 'Unknown Error'; - } catch { - return 'Connection Error'; + const res = await makeAPIPOSTRequest( + 'api/startdm', + query, + ); + if (res.errors) { + return res.errors[0]; } + if (res.channel) { + return res.channel; + } + return t`Unknown Error`; } /* * set receiving of all DMs on/off - * block true if blocking all dms, false if unblocking - * return error string or null if successful + * @param block true if blocking all dms, false if unblocking + * @return error string or null if successful */ export async function requestBlockDm(block: boolean) { - const response = await fetchWithTimeout('api/blockdm', { - method: 'POST', - credentials: 'include', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ block }), - }); - - try { - const res = await response.json(); - if (res.errors) { - return res.errors[0]; - } - if (response.ok && res.status === 'ok') { - return null; - } - return 'Unknown Error'; - } catch { - return 'Connection Error'; + const res = await makeAPIPOSTRequest( + 'api/blockdm', + { block }, + ); + if (res.errors) { + return res.errors[0]; } + if (res.status === 'ok') { + return null; + } + return t`Unknown Error`; } /* * leaving Chat Channel (i.e. DM channel) - * channelId 8nteger id of channel - * return error string or null if successful + * @param channelId 8nteger id of channel + * @return error string or null if successful */ export async function requestLeaveChan(channelId: boolean) { - const response = await fetchWithTimeout('api/leavechan', { - method: 'POST', - credentials: 'include', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ channelId }), - }); - - try { - const res = await response.json(); - if (res.errors) { - return res.errors[0]; - } - if (response.ok && res.status === 'ok') { - return null; - } - return 'Unknown Error'; - } catch { - return 'Connection Error'; + const res = await makeAPIPOSTRequest( + 'api/leavechan', + { channelId }, + ); + if (res.errors) { + return res.errors[0]; } + if (res.status === 'ok') { + return null; + } + return t`Unknown Error`; +} + +export function requestSolveCaptcha(text) { + return makeAPIPOSTRequest( + 'api/captcha', + { text }, + ); +} + +export function requestPasswordChange(newPassword, password) { + return makeAPIPOSTRequest( + 'api/auth/change_passwd', + { password, newPassword }, + ); +} + +export async function requestResendVerify() { + return makeAPIGETRequest( + './api/auth/resend_verify', + ); +} + +export function requestMcLink(accepted) { + return makeAPIPOSTRequest( + 'api/auth/mclink', + { accepted }, + ); +} + +export function requestNameChange(name) { + return makeAPIPOSTRequest( + 'api/auth/change_name', + { name }, + ); +} + +export function requestMailChange(email, password) { + return makeAPIPOSTRequest( + 'api/auth/change_mail', + { email, password }, + ); +} + +export function requestLogin(nameoremail, password) { + return makeAPIPOSTRequest( + 'api/auth/local', + { nameoremail, password }, + ); +} + +export function requestRegistration(name, email, password) { + return makeAPIPOSTRequest( + 'api/auth/register', + { name, email, password }, + ); +} + +export function requestNewPassword(email) { + return makeAPIPOSTRequest( + 'api/auth/restore_password', + { email }, + ); +} + +export function requestDeleteAccount(password) { + return makeAPIPOSTRequest( + 'api/auth/delete_account', + { password }, + ); } diff --git a/src/components/ChangeMail.jsx b/src/components/ChangeMail.jsx index 8436c04..67bee29 100644 --- a/src/components/ChangeMail.jsx +++ b/src/components/ChangeMail.jsx @@ -6,8 +6,9 @@ import React from 'react'; import { t } from 'ttag'; import { - validateEMail, validatePassword, parseAPIresponse, + validateEMail, validatePassword, } from '../utils/validation'; +import { requestMailChange } from '../actions/fetch'; function validate(email, password) { const errors = []; @@ -20,23 +21,6 @@ function validate(email, password) { return errors; } -async function submitMailchange(email, password) { - const body = JSON.stringify({ - email, - password, - }); - const response = await fetch('./api/auth/change_mail', { - method: 'POST', - headers: { - 'Content-type': 'application/json', - }, - body, - credentials: 'include', - }); - - return parseAPIresponse(response); -} - class ChangeMail extends React.Component { constructor() { super(); @@ -64,7 +48,7 @@ class ChangeMail extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors } = await submitMailchange(email, password); + const { errors: resperrors } = await requestMailChange(email, password); if (resperrors) { this.setState({ errors: resperrors, diff --git a/src/components/ChangeName.jsx b/src/components/ChangeName.jsx index 974944b..40d9dfc 100644 --- a/src/components/ChangeName.jsx +++ b/src/components/ChangeName.jsx @@ -5,7 +5,8 @@ import React from 'react'; import { t } from 'ttag'; -import { validateName, parseAPIresponse } from '../utils/validation'; +import { validateName } from '../utils/validation'; +import { requestNameChange } from '../actions/fetch'; function validate(name) { @@ -17,22 +18,6 @@ function validate(name) { return errors; } -async function submitNamechange(name) { - const body = JSON.stringify({ - name, - }); - const response = await fetch('./api/auth/change_name', { - method: 'POST', - headers: { - 'Content-type': 'application/json', - }, - body, - credentials: 'include', - }); - - return parseAPIresponse(response); -} - class ChangeName extends React.Component { constructor() { super(); @@ -58,7 +43,7 @@ class ChangeName extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors } = await submitNamechange(name); + const { errors: resperrors } = await requestNameChange(name); if (resperrors) { this.setState({ errors: resperrors, diff --git a/src/components/ChangePassword.jsx b/src/components/ChangePassword.jsx index 37306ef..fbe0292 100644 --- a/src/components/ChangePassword.jsx +++ b/src/components/ChangePassword.jsx @@ -5,7 +5,8 @@ import React from 'react'; import { t } from 'ttag'; -import { validatePassword, parseAPIresponse } from '../utils/validation'; +import { validatePassword } from '../utils/validation'; +import { requestPasswordChange } from '../actions/fetch'; function validate(mailreg, password, newPassword, confirmPassword) { const errors = []; @@ -24,24 +25,6 @@ function validate(mailreg, password, newPassword, confirmPassword) { return errors; } -async function submitPasswordChange(newPassword, password) { - const body = JSON.stringify({ - password, - newPassword, - }); - const response = await fetch('./api/auth/change_passwd', { - method: 'POST', - headers: { - 'Content-type': 'application/json', - }, - body, - credentials: 'include', - }); - - return parseAPIresponse(response); -} - - class ChangePassword extends React.Component { constructor() { super(); @@ -78,7 +61,7 @@ class ChangePassword extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors } = await submitPasswordChange( + const { errors: resperrors } = await requestPasswordChange( newPassword, password, ); diff --git a/src/components/DeleteAccount.jsx b/src/components/DeleteAccount.jsx index d4ec2df..4efb5b6 100644 --- a/src/components/DeleteAccount.jsx +++ b/src/components/DeleteAccount.jsx @@ -7,7 +7,8 @@ import React from 'react'; import { connect } from 'react-redux'; import { t } from 'ttag'; -import { validatePassword, parseAPIresponse } from '../utils/validation'; +import { validatePassword } from '../utils/validation'; +import { requestDeleteAccount } from '../actions/fetch'; import { logoutUser } from '../actions'; function validate(password) { @@ -19,22 +20,6 @@ function validate(password) { return errors; } -async function submitDeleteAccount(password) { - const body = JSON.stringify({ - password, - }); - const response = await fetch('./api/auth/delete_account', { - method: 'POST', - headers: { - 'Content-type': 'application/json', - }, - body, - credentials: 'include', - }); - - return parseAPIresponse(response); -} - class DeleteAccount extends React.Component { constructor() { super(); @@ -60,7 +45,7 @@ class DeleteAccount extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors } = await submitDeleteAccount(password); + const { errors: resperrors } = await requestDeleteAccount(password); if (resperrors) { this.setState({ errors: resperrors, diff --git a/src/components/HelpModal.jsx b/src/components/HelpModal.jsx index 4af09da..8818104 100644 --- a/src/components/HelpModal.jsx +++ b/src/components/HelpModal.jsx @@ -31,11 +31,6 @@ const HelpModal = () => { const bindShift = ⇧ {c('keybinds').t`Shift`}; const bindC = {c('keybinds').t`C`}; - const hCaptchaPP = {t`Privacy Policy`}; - const reCaptchaPP = {t`Privacy Policy`}; - const hCaptchaTOS = {t`Terms of Service`}; - const reCaptchaTOS = {t`Terms of Service`}; - const guildedLink = guilded; const getIPLink = {t`your IP`}; const mailLink = pixelplanetdev@gmail.com; diff --git a/src/components/LogInForm.jsx b/src/components/LogInForm.jsx index 588e46c..9ad2044 100644 --- a/src/components/LogInForm.jsx +++ b/src/components/LogInForm.jsx @@ -7,8 +7,9 @@ import { connect } from 'react-redux'; import { t } from 'ttag'; import { - validateEMail, validateName, validatePassword, parseAPIresponse, + validateEMail, validateName, validatePassword, } from '../utils/validation'; +import { requestLogin } from '../actions/fetch'; import { loginUser } from '../actions'; @@ -24,22 +25,6 @@ function validate(nameoremail, password) { return errors; } -async function submitLogin(nameoremail, password) { - const body = JSON.stringify({ - nameoremail, - password, - }); - const response = await fetch('./api/auth/local', { - method: 'POST', - body, - headers: { - 'Content-Type': 'application/json', - }, - }); - - return parseAPIresponse(response); -} - const inputStyles = { display: 'inline-block', width: '100%', @@ -73,7 +58,7 @@ class LogInForm extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors, me } = await submitLogin( + const { errors: resperrors, me } = await requestLogin( nameoremail, password, ); diff --git a/src/components/NewPasswordForm.jsx b/src/components/NewPasswordForm.jsx index 08a46aa..6544c6d 100644 --- a/src/components/NewPasswordForm.jsx +++ b/src/components/NewPasswordForm.jsx @@ -4,7 +4,8 @@ */ import React from 'react'; import { t } from 'ttag'; -import { validateEMail, parseAPIresponse } from '../utils/validation'; +import { validateEMail } from '../utils/validation'; +import { requestNewPassword } from '../actions/fetch'; function validate(email) { const errors = []; @@ -13,21 +14,6 @@ function validate(email) { return errors; } -async function submitNewpass(email) { - const body = JSON.stringify({ - email, - }); - const response = await fetch('./api/auth/restore_password', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body, - }); - - return parseAPIresponse(response); -} - const inputStyles = { display: 'inline-block', width: '100%', @@ -60,7 +46,7 @@ class NewPasswordForm extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors } = await submitNewpass(email); + const { errors: resperrors } = await requestNewPassword(email); if (resperrors) { this.setState({ errors: resperrors, diff --git a/src/components/SignUpForm.jsx b/src/components/SignUpForm.jsx index 74a1650..6a9afc5 100644 --- a/src/components/SignUpForm.jsx +++ b/src/components/SignUpForm.jsx @@ -7,8 +7,9 @@ import React from 'react'; import { connect } from 'react-redux'; import { t } from 'ttag'; import { - validateEMail, validateName, validatePassword, parseAPIresponse, + validateEMail, validateName, validatePassword, } from '../utils/validation'; +import { requestRegistration } from '../actions/fetch'; import { showUserAreaModal, loginUser } from '../actions'; @@ -28,25 +29,6 @@ function validate(name, email, password, confirmPassword) { return errors; } - -async function submitRegistration(name, email, password) { - const body = JSON.stringify({ - name, - email, - password, - }); - const response = await fetch('./api/auth/register', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body, - credentials: 'include', - }); - - return parseAPIresponse(response); -} - const inputStyles = { display: 'inline-block', width: '100%', @@ -83,7 +65,7 @@ class SignUpForm extends React.Component { if (errors.length > 0) return; this.setState({ submitting: true }); - const { errors: resperrors, me } = await submitRegistration( + const { errors: resperrors, me } = await requestRegistration( name, email, password, diff --git a/src/components/UserMessages.jsx b/src/components/UserMessages.jsx index 0025edf..27441ec 100644 --- a/src/components/UserMessages.jsx +++ b/src/components/UserMessages.jsx @@ -6,8 +6,8 @@ import React from 'react'; import { connect } from 'react-redux'; import { t } from 'ttag'; -import { parseAPIresponse } from '../utils/validation'; import { setMinecraftName, remFromMessages } from '../actions'; +import { requestResendVerify, requestMcLink } from '../actions/fetch'; class UserMessages extends React.Component { @@ -31,11 +31,8 @@ class UserMessages extends React.Component { resentVerify: true, }); - const response = await fetch('./api/auth/resend_verify', { - credentials: 'include', - }); + const { errors } = await requestResendVerify(); - const { errors } = await parseAPIresponse(response); const verifyAnswer = (errors) ? errors[0] : t`A new verification mail is getting sent to you.`; @@ -50,15 +47,9 @@ class UserMessages extends React.Component { this.setState({ sentLink: true, }); - const body = JSON.stringify({ accepted }); - const rep = await fetch('./api/auth/mclink', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body, - credentials: 'include', - }); - const { errors } = parseAPIresponse(rep); + const { errors } = await requestMcLink(accepted); + if (errors) { this.setState({ linkAnswer: errors[0], diff --git a/src/utils/validation.js b/src/utils/validation.js index ba09a54..7299d4d 100644 --- a/src/utils/validation.js +++ b/src/utils/validation.js @@ -61,23 +61,3 @@ export function validatePassword(password) { } return false; } - -/* - * makes sure that responses from the api - * includes errors when failure occures - */ -export async function parseAPIresponse(response) { - try { - const resp = await response.json(); - if (!response.ok && !resp.errors) { - return { - errors: [t`Could not connect to server, please try again later :(`], - }; - } - return resp; - } catch (e) { - return { - errors: [t`I think we experienced some error :(`], - }; - } -}