diff options
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/api/api.service.js | 46 | ||||
| -rw-r--r-- | src/services/backend_interactor_service/backend_interactor_service.js | 7 | ||||
| -rw-r--r-- | src/services/entity_normalizer/entity_normalizer.service.js | 4 | ||||
| -rw-r--r-- | src/services/errors/errors.js | 35 | ||||
| -rw-r--r-- | src/services/follow_manipulate/follow_manipulate.js | 30 | ||||
| -rw-r--r-- | src/services/new_api/password_reset.js | 18 |
6 files changed, 95 insertions, 45 deletions
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index d4ad1c4e..887d7d7a 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1,18 +1,14 @@ import { each, map, concat, last } from 'lodash' import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js' import 'whatwg-fetch' -import { StatusCodeError } from '../errors/errors' +import { RegistrationError, StatusCodeError } from '../errors/errors' /* eslint-env browser */ -const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json' const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' const BLOCKS_IMPORT_URL = '/api/pleroma/blocks_import' const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import' const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account' const CHANGE_PASSWORD_URL = '/api/pleroma/change_password' -const FOLLOW_REQUESTS_URL = '/api/pleroma/friend_requests' -const APPROVE_USER_URL = '/api/pleroma/friendships/approve' -const DENY_USER_URL = '/api/pleroma/friendships/deny' const TAG_USER_URL = '/api/pleroma/admin/users/tag' const PERMISSION_GROUP_URL = (screenName, right) => `/api/pleroma/admin/users/${screenName}/permission_group/${right}` const ACTIVATION_STATUS_URL = screenName => `/api/pleroma/admin/users/${screenName}/activation_status` @@ -40,6 +36,9 @@ const MASTODON_FOLLOW_URL = id => `/api/v1/accounts/${id}/follow` const MASTODON_UNFOLLOW_URL = id => `/api/v1/accounts/${id}/unfollow` const MASTODON_FOLLOWING_URL = id => `/api/v1/accounts/${id}/following` const MASTODON_FOLLOWERS_URL = id => `/api/v1/accounts/${id}/followers` +const MASTODON_FOLLOW_REQUESTS_URL = '/api/v1/follow_requests' +const MASTODON_APPROVE_USER_URL = id => `/api/v1/follow_requests/${id}/authorize` +const MASTODON_DENY_USER_URL = id => `/api/v1/follow_requests/${id}/reject` const MASTODON_DIRECT_MESSAGES_TIMELINE_URL = '/api/v1/timelines/direct' const MASTODON_PUBLIC_TIMELINE = '/api/v1/timelines/public' const MASTODON_USER_HOME_TIMELINE_URL = '/api/v1/timelines/home' @@ -67,6 +66,8 @@ const MASTODON_PROFILE_UPDATE_URL = '/api/v1/accounts/update_credentials' const MASTODON_REPORT_USER_URL = '/api/v1/reports' const MASTODON_PIN_OWN_STATUS = id => `/api/v1/statuses/${id}/pin` const MASTODON_UNPIN_OWN_STATUS = id => `/api/v1/statuses/${id}/unpin` +const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute` +const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute` const MASTODON_SEARCH_2 = `/api/v2/search` const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' @@ -199,12 +200,11 @@ const register = ({ params, credentials }) => { ...rest }) }) - .then((response) => [response.ok, response]) - .then(([ok, response]) => { - if (ok) { + .then((response) => { + if (response.ok) { return response.json() } else { - return response.json().then((error) => { throw new Error(error) }) + return response.json().then((error) => { throw new RegistrationError(error) }) } }) } @@ -219,14 +219,6 @@ const authHeaders = (accessToken) => { } } -const externalProfile = ({ profileUrl, credentials }) => { - let url = `${EXTERNAL_PROFILE_URL}?profileurl=${profileUrl}` - return fetch(url, { - headers: authHeaders(credentials), - method: 'GET' - }).then((data) => data.json()) -} - const followUser = ({ id, credentials }) => { let url = MASTODON_FOLLOW_URL(id) return fetch(url, { @@ -253,6 +245,16 @@ const unpinOwnStatus = ({ id, credentials }) => { .then((data) => parseStatus(data)) } +const muteConversation = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_MUTE_CONVERSATION(id), credentials, method: 'POST' }) + .then((data) => parseStatus(data)) +} + +const unmuteConversation = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_UNMUTE_CONVERSATION(id), credentials, method: 'POST' }) + .then((data) => parseStatus(data)) +} + const blockUser = ({ id, credentials }) => { return fetch(MASTODON_BLOCK_USER_URL(id), { headers: authHeaders(credentials), @@ -268,7 +270,7 @@ const unblockUser = ({ id, credentials }) => { } const approveUser = ({ id, credentials }) => { - let url = `${APPROVE_USER_URL}?user_id=${id}` + let url = MASTODON_APPROVE_USER_URL(id) return fetch(url, { headers: authHeaders(credentials), method: 'POST' @@ -276,7 +278,7 @@ const approveUser = ({ id, credentials }) => { } const denyUser = ({ id, credentials }) => { - let url = `${DENY_USER_URL}?user_id=${id}` + let url = MASTODON_DENY_USER_URL(id) return fetch(url, { headers: authHeaders(credentials), method: 'POST' @@ -352,9 +354,10 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => { } const fetchFollowRequests = ({ credentials }) => { - const url = FOLLOW_REQUESTS_URL + const url = MASTODON_FOLLOW_REQUESTS_URL return fetch(url, { headers: authHeaders(credentials) }) .then((data) => data.json()) + .then((data) => data.map(parseUser)) } const fetchConversation = ({ id, credentials }) => { @@ -921,6 +924,8 @@ const apiService = { unfollowUser, pinOwnStatus, unpinOwnStatus, + muteConversation, + unmuteConversation, blockUser, unblockUser, fetchUser, @@ -952,7 +957,6 @@ const apiService = { updateBg, updateProfile, updateBanner, - externalProfile, importBlocks, importFollows, deleteAccount, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index bdfe0465..3c44a10c 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -117,6 +117,8 @@ const backendInteractorService = credentials => { const fetchPinnedStatuses = (id) => apiService.fetchPinnedStatuses({ credentials, id }) const pinOwnStatus = (id) => apiService.pinOwnStatus({ credentials, id }) const unpinOwnStatus = (id) => apiService.unpinOwnStatus({ credentials, id }) + const muteConversation = (id) => apiService.muteConversation({ credentials, id }) + const unmuteConversation = (id) => apiService.unmuteConversation({ credentials, id }) const getCaptcha = () => apiService.getCaptcha() const register = (params) => apiService.register({ credentials, params }) @@ -125,8 +127,6 @@ const backendInteractorService = credentials => { const updateBanner = ({ banner }) => apiService.updateBanner({ credentials, banner }) const updateProfile = ({ params }) => apiService.updateProfile({ credentials, params }) - const externalProfile = (profileUrl) => apiService.externalProfile({ profileUrl, credentials }) - const importBlocks = (file) => apiService.importBlocks({ file, credentials }) const importFollows = (file) => apiService.importFollows({ file, credentials }) @@ -178,6 +178,8 @@ const backendInteractorService = credentials => { fetchPinnedStatuses, pinOwnStatus, unpinOwnStatus, + muteConversation, + unmuteConversation, tagUser, untagUser, addRight, @@ -190,7 +192,6 @@ const backendInteractorService = credentials => { updateBg, updateBanner, updateProfile, - externalProfile, importBlocks, importFollows, deleteAccount, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index de6664d1..6cc1851d 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -65,6 +65,7 @@ export const parseUser = (data) => { if (relationship) { output.follows_you = relationship.followed_by + output.requested = relationship.requested output.following = relationship.following output.statusnet_blocking = relationship.blocking output.muted = relationship.muting @@ -152,7 +153,7 @@ export const parseUser = (data) => { output.statuses_count = data.statuses_count output.friendIds = [] output.followerIds = [] - output.pinnedStatuseIds = [] + output.pinnedStatusIds = [] if (data.pleroma) { output.follow_request_count = data.pleroma.follow_request_count @@ -240,6 +241,7 @@ export const parseStatus = (data) => { output.external_url = data.url output.poll = data.poll output.pinned = data.pinned + output.muted = data.muted } else { output.favorited = data.favorited output.fave_num = data.fave_num diff --git a/src/services/errors/errors.js b/src/services/errors/errors.js index 548f3c68..590552da 100644 --- a/src/services/errors/errors.js +++ b/src/services/errors/errors.js @@ -1,3 +1,5 @@ +import { humanizeErrors } from '../../modules/errors' + export function StatusCodeError (statusCode, body, options, response) { this.name = 'StatusCodeError' this.statusCode = statusCode @@ -12,3 +14,36 @@ export function StatusCodeError (statusCode, body, options, response) { } StatusCodeError.prototype = Object.create(Error.prototype) StatusCodeError.prototype.constructor = StatusCodeError + +export class RegistrationError extends Error { + constructor (error) { + super() + if (Error.captureStackTrace) { + Error.captureStackTrace(this) + } + + try { + // the error is probably a JSON object with a single key, "errors", whose value is another JSON object containing the real errors + if (typeof error === 'string') { + error = JSON.parse(error) + if (error.hasOwnProperty('error')) { + error = JSON.parse(error.error) + } + } + + if (typeof error === 'object') { + // replace ap_id with username + if (error.ap_id) { + error.username = error.ap_id + delete error.ap_id + } + this.message = humanizeErrors(error) + } else { + this.message = error + } + } catch (e) { + // can't parse it, so just treat it like a string + this.message = error + } + } +} diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js index b2486e7c..529fdb9b 100644 --- a/src/services/follow_manipulate/follow_manipulate.js +++ b/src/services/follow_manipulate/follow_manipulate.js @@ -2,17 +2,17 @@ const fetchUser = (attempt, user, store) => new Promise((resolve, reject) => { setTimeout(() => { store.state.api.backendInteractor.fetchUser({ id: user.id }) .then((user) => store.commit('addNewUsers', [user])) - .then(() => resolve([user.following, attempt])) + .then(() => resolve([user.following, user.requested, user.locked, attempt])) .catch((e) => reject(e)) }, 500) -}).then(([following, attempt]) => { - if (!following && attempt <= 3) { +}).then(([following, sent, locked, attempt]) => { + if (!following && !(locked && sent) && attempt <= 3) { // If we BE reports that we still not following that user - retry, // increment attempts by one return fetchUser(++attempt, user, store) } else { // If we run out of attempts, just return whatever status is. - return following + return sent } }) @@ -21,14 +21,10 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => { .then((updated) => { store.commit('updateUserRelationship', [updated]) - // For locked users we just mark it that we sent the follow request - if (updated.locked) { - resolve({ sent: true }) - } - - if (updated.following) { - // If we get result immediately, just stop. - resolve({ sent: false }) + if (updated.following || (user.locked && user.requested)) { + // If we get result immediately or the account is locked, just stop. + resolve({ sent: updated.requested }) + return } // But usually we don't get result immediately, so we ask server @@ -39,14 +35,8 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => { // Recursive Promise, it will call itself up to 3 times. return fetchUser(1, user, store) - .then((following) => { - if (following) { - // We confirmed and everything's good. - resolve({ sent: false }) - } else { - // If after all the tries, just treat it as if user is locked - resolve({ sent: false }) - } + .then((sent) => { + resolve({ sent }) }) }) }) diff --git a/src/services/new_api/password_reset.js b/src/services/new_api/password_reset.js new file mode 100644 index 00000000..43199625 --- /dev/null +++ b/src/services/new_api/password_reset.js @@ -0,0 +1,18 @@ +import { reduce } from 'lodash' + +const MASTODON_PASSWORD_RESET_URL = `/auth/password` + +const resetPassword = ({ instance, email }) => { + const params = { email } + const query = reduce(params, (acc, v, k) => { + const encoded = `${k}=${encodeURIComponent(v)}` + return `${acc}&${encoded}` + }, '') + const url = `${instance}${MASTODON_PASSWORD_RESET_URL}?${query}` + + return window.fetch(url, { + method: 'POST' + }) +} + +export default resetPassword |
