aboutsummaryrefslogtreecommitdiff
path: root/src/services
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2019-09-08 13:44:29 +0300
committerHenry Jameson <me@hjkos.com>2019-09-08 13:44:29 +0300
commitdb086fe1fdeefdc904f51ee00b2710f089996599 (patch)
tree6e4734fc99544da9b34c78700b18c9b02a3f573f /src/services
parent5851f97eb058b3e2df91f9122ba899bc7e4affaf (diff)
parente75ac9ddbc66a7e3cd40ef130b26b06b8cec9f1d (diff)
Merge remote-tracking branch 'upstream/develop' into emoji-selector-update
* upstream/develop: (116 commits) Password reset page add a comment force img updating immediately Fixed "sequimiento" to "seguimiento". Replace `/api/externalprofile/show.json` with a MastoAPI equialent Use mastodon api in follow requests "Optional" in lowercase. Update es.json fix pin/unpin status logic rename a mutation update fix user avatar fallback logic remove dead code Corrected "Media Proxy" translation. Update es.json make bio textarea resizable vertically only remove dead code Make image orientation consistent on FF, fix videos w/ modal remove dead code fix crazy watch logic in conversation ...
Diffstat (limited to 'src/services')
-rw-r--r--src/services/api/api.service.js46
-rw-r--r--src/services/backend_interactor_service/backend_interactor_service.js7
-rw-r--r--src/services/entity_normalizer/entity_normalizer.service.js4
-rw-r--r--src/services/errors/errors.js35
-rw-r--r--src/services/follow_manipulate/follow_manipulate.js30
-rw-r--r--src/services/new_api/password_reset.js18
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