From afde68ae5bae6aac64ceaf4b21d9dff0f1568cf8 Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Fri, 25 Jan 2019 20:29:32 +0300 Subject: [PATCH] Little refactoring of the accounts API for the frontend application --- src/components/user/actions.js | 12 ++- src/services/api/accounts.js | 145 +++++++++++++++-------------- src/services/api/authentication.js | 50 +++++----- 3 files changed, 110 insertions(+), 97 deletions(-) diff --git a/src/components/user/actions.js b/src/components/user/actions.js index 2342dd5..af26030 100644 --- a/src/components/user/actions.js +++ b/src/components/user/actions.js @@ -1,4 +1,8 @@ -import accounts from 'services/api/accounts'; +import { + getInfo as getInfoEndpoint, + changeLang as changeLangEndpoint, + acceptRules as acceptRulesEndpoint, +} from 'services/api/accounts'; import { setLocale } from 'components/i18n/actions'; export const UPDATE = 'USER_UPDATE'; @@ -36,7 +40,7 @@ export function changeLang(lang) { const {user: {isGuest, lang: oldLang}} = getState(); if (oldLang !== lang) { - !isGuest && accounts.changeLang(lang); + !isGuest && changeLangEndpoint(lang); dispatch({ type: CHANGE_LANG, @@ -59,7 +63,7 @@ export function setGuest() { export function fetchUserData() { return (dispatch) => - accounts.current() + getInfoEndpoint(0) .then((resp) => { dispatch(updateUser({ isGuest: false, @@ -72,7 +76,7 @@ export function fetchUserData() { export function acceptRules() { return (dispatch) => - accounts.acceptRules().then((resp) => { + acceptRulesEndpoint().then((resp) => { dispatch(updateUser({ shouldAcceptRules: false })); diff --git a/src/services/api/accounts.js b/src/services/api/accounts.js index 145e51a..c840fc3 100644 --- a/src/services/api/accounts.js +++ b/src/services/api/accounts.js @@ -1,7 +1,7 @@ // @flow import request from 'services/request'; -type UserResponse = { +export type UserResponse = { elyProfileLink: string, email: string, hasMojangUsernameCollision: bool, @@ -16,6 +16,79 @@ type UserResponse = { uuid: string, }; +export function getInfo(id: number, options: { token?: ?string } = {}): Promise { + return request.get(`/api/v1/accounts/${id}`, {}, { + token: options.token, + }); +} + +export function changePassword({ + password = '', + newPassword = '', + newRePassword = '', + logoutAll = true, +}: { + password?: string, + newPassword?: string, + newRePassword?: string, + logoutAll?: bool, +}) { + return request.post('/api/accounts/change-password', { + password, + newPassword, + newRePassword, + logoutAll, + }); +} + +export function acceptRules() { + return request.post('/api/accounts/accept-rules'); +} + +export function changeUsername({ + username = '', + password = '', +}: { + username?: string, + password?: string, +}) { + return request.post('/api/accounts/change-username', { + username, + password, + }); +} + +export function changeLang(lang: string) { + return request.post('/api/accounts/change-lang', { + lang, + }); +} + +export function requestEmailChange({ password = '' }: { password?: string }) { + return request.post('/api/accounts/change-email/initialize', { + password, + }); +} + +export function setNewEmail({ + email = '', + key = '', +}: { + email?: string, + key?: string, +}) { + return request.post('/api/accounts/change-email/submit-new-email', { + email, + key, + }); +} + +export function confirmNewEmail({ key }: { key: string }) { + return request.post('/api/accounts/change-email/confirm-new-email', { + key, + }); +} + export default { /** * @param {object} options @@ -25,76 +98,8 @@ export default { * @return {Promise} */ current(options: { token?: ?string } = {}): Promise { - return request.get('/api/accounts/current', {}, { - token: options.token - }); + return getInfo(0, options); }, - changePassword({ - password = '', - newPassword = '', - newRePassword = '', - logoutAll = true - }: { - password?: string, - newPassword?: string, - newRePassword?: string, - logoutAll?: bool, - }) { - return request.post( - '/api/accounts/change-password', - {password, newPassword, newRePassword, logoutAll} - ); - }, - acceptRules() { - return request.post('/api/accounts/accept-rules'); - }, - - changeUsername({ - username = '', - password = '' - }: { - username?: string, - password?: string, - }) { - return request.post( - '/api/accounts/change-username', - {username, password} - ); - }, - - changeLang(lang: string) { - return request.post( - '/api/accounts/change-lang', - {lang} - ); - }, - - requestEmailChange({password = ''}: { password?: string }) { - return request.post( - '/api/accounts/change-email/initialize', - {password} - ); - }, - - setNewEmail({ - email = '', - key = '' - }: { - email?: string, - key?: string, - }) { - return request.post( - '/api/accounts/change-email/submit-new-email', - {email, key} - ); - }, - - confirmNewEmail({key}: { key: string }) { - return request.post( - '/api/accounts/change-email/confirm-new-email', - {key} - ); - } }; diff --git a/src/services/api/authentication.js b/src/services/api/authentication.js index 86d13b9..f3bdde1 100644 --- a/src/services/api/authentication.js +++ b/src/services/api/authentication.js @@ -1,7 +1,8 @@ // @flow +import type { UserResponse } from 'services/api/accounts'; import logger from 'services/logger'; import request, { InternalServerError } from 'services/request'; -import accounts from 'services/api/accounts'; +import { getInfo as getInfoEndpoint } from 'services/api/accounts'; const authentication = { login({ @@ -70,35 +71,38 @@ const authentication = { /** * Resolves if token is valid * - * @param {object} options - * @param {string} options.token - * @param {string} options.refreshToken + * @param {string} token + * @param {string} refreshToken * * @return {Promise} - resolves with options.token or with a new token * if it was refreshed. As a side effect the response * will have a `user` field with current user data + * */ - validateToken({token, refreshToken}: { + async validateToken(token: string, refreshToken: ?string): Promise<{ token: string, - refreshToken: ?string - }) { - return new Promise((resolve) => { - if (typeof token !== 'string') { - throw new Error('token must be a string'); - } + refreshToken: ?string, + user: UserResponse, + }> { + if (typeof token !== 'string') { + throw new Error('token must be a string'); + } - resolve(); - }) - .then(() => accounts.current({token})) - .then((user) => ({token, refreshToken, user})) - .catch((resp) => - this.handleTokenError(resp, refreshToken) - // TODO: use recursion here - .then(({token}) => - accounts.current({token}) - .then((user) => ({token, refreshToken, user})) - ) - ); + // TODO: decode token to extract information about user id + + let user: UserResponse; + try { + user = await getInfoEndpoint(0, { token }); + } catch (resp) { + const { token } = await this.handleTokenError(resp, refreshToken); + user = await getInfoEndpoint(0, { token }); // TODO: replace with recursive call + } + + return { + token, + refreshToken, + user, + }; }, handleTokenError(resp: Error | { message: string }, refreshToken: ?string): Promise<{