diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index f5c2d1c88..2ad111874 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -127,7 +127,6 @@ "mobile.account_notifications.threads_mentions": "Mentions in threads", "mobile.account_notifications.threads_start": "Threads that I start", "mobile.account_notifications.threads_start_participate": "Threads that I start or participate in", - "mobile.account.settings.cancel": "Cancel", "mobile.account.settings.save": "Save", "mobile.action_menu.select": "Select an option", "mobile.advanced_settings.clockDisplay": "Clock display", @@ -401,6 +400,7 @@ "mobile.routes.thread": "{channelName} Thread", "mobile.routes.thread_dm": "Direct Message Thread", "mobile.routes.user_profile": "Profile", + "mobile.routes.user_profile.edit": "Edit", "mobile.routes.user_profile.local_time": "LOCAL TIME", "mobile.routes.user_profile.send_message": "Send Message", "mobile.search.after_modifier_description": "to find posts after a specific date", diff --git a/share_extension/android/extension_post/extension_post.js b/share_extension/android/extension_post/extension_post.js index d4afdad8b..a1cfa5679 100644 --- a/share_extension/android/extension_post/extension_post.js +++ b/share_extension/android/extension_post/extension_post.js @@ -21,7 +21,9 @@ import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; import Video from 'react-native-video'; import LocalAuth from 'react-native-local-auth'; import RNFetchBlob from 'rn-fetch-blob'; +import {getGenericPassword} from 'react-native-keychain'; +import {Client4} from 'mattermost-redux/client'; import {Preferences} from 'mattermost-redux/constants'; import {getFormattedFileSize, lookupMimeType} from 'mattermost-redux/utils/file_utils'; @@ -29,8 +31,10 @@ import Loading from 'app/components/loading'; import PaperPlane from 'app/components/paper_plane'; import {MAX_FILE_COUNT} from 'app/constants/post_textbox'; import mattermostManaged from 'app/mattermost_managed'; +import avoidNativeBridge from 'app/utils/avoid_native_bridge'; import {getExtensionFromMime} from 'app/utils/file'; import {emptyFunction} from 'app/utils/general'; +import {setCSRFFromCookie} from 'app/utils/security'; import {preventDoubleTap} from 'app/utils/tap'; import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -45,6 +49,7 @@ import { import ChannelButton from './channel_button'; import TeamButton from './team_button'; +const {Initialization} = NativeModules; const defaultTheme = Preferences.THEMES.default; const extensionSvg = { csv: ExcelSvg, @@ -70,8 +75,6 @@ export default class ExtensionPost extends PureComponent { maxFileSize: PropTypes.number.isRequired, navigation: PropTypes.object.isRequired, teamId: PropTypes.string.isRequired, - token: PropTypes.string, - url: PropTypes.string, }; static contextTypes = { @@ -227,6 +230,43 @@ export default class ExtensionPost extends PureComponent { }); } + getAppCredentials = async () => { + try { + const credentials = await avoidNativeBridge( + () => { + return Initialization.credentialsExist; + }, + () => { + return Initialization.credentials; + }, + () => { + return getGenericPassword(); + } + ); + + if (credentials) { + const passwordParsed = credentials.password.split(','); + + // password == token, url + if (passwordParsed.length === 2) { + const [token, url] = passwordParsed; + + if (url && url !== 'undefined' && token && token !== 'undefined') { + this.token = token; + this.url = url; + Client4.setUrl(url); + Client4.setToken(token); + await setCSRFFromCookie(url); + } + } + } + } catch (error) { + return null; + } + + return null; + }; + getInputRef = (ref) => { this.input = ref; }; @@ -294,6 +334,8 @@ export default class ExtensionPost extends PureComponent { }; initialize = async () => { + await this.getAppCredentials(); + const hasPermission = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE); let granted; if (!hasPermission) { @@ -311,8 +353,8 @@ export default class ExtensionPost extends PureComponent { }; loadData = async (items) => { - const {actions, maxFileSize, teamId, token, url} = this.props; - if (token && url) { + const {actions, maxFileSize, teamId} = this.props; + if (this.token && this.url) { const text = []; const files = []; let totalSize = 0; @@ -379,14 +421,14 @@ export default class ExtensionPost extends PureComponent { onPost = () => { const {channelId, files, value} = this.state; - const {currentUserId, token, url} = this.props; + const {currentUserId} = this.props; const data = { channelId, currentUserId, files, - token, - url, + token: this.token, + url: this.url, value, }; @@ -542,7 +584,7 @@ export default class ExtensionPost extends PureComponent { render() { const {formatMessage} = this.context.intl; - const {maxFileSize, token, url} = this.props; + const {maxFileSize} = this.props; const {error, hasPermission, files, totalSize, loaded} = this.state; if (!loaded) { @@ -555,7 +597,7 @@ export default class ExtensionPost extends PureComponent { return this.renderErrorMessage(error); } - if (token && url) { + if (this.token && this.url) { if (hasPermission === false) { const storage = formatMessage({ id: 'mobile.extension.permission', diff --git a/share_extension/android/extension_post/index.js b/share_extension/android/extension_post/index.js index 6167f7e4d..08d3504f3 100644 --- a/share_extension/android/extension_post/index.js +++ b/share_extension/android/extension_post/index.js @@ -16,8 +16,7 @@ import ExtensionPost from './extension_post'; function mapStateToProps(state) { const config = getConfig(state); - const {credentials} = state.entities.general; - const {token, url} = credentials; + let channel = getCurrentChannel(state); if (channel && channel.delete_at !== 0) { channel = getDefaultChannel(state); @@ -29,8 +28,6 @@ function mapStateToProps(state) { currentUserId: getCurrentUserId(state), maxFileSize: getAllowedServerMaxFileSize(config), teamId: getCurrentTeamId(state), - token, - url, }; } diff --git a/share_extension/android/index.js b/share_extension/android/index.js index b28febef9..305a28627 100644 --- a/share_extension/android/index.js +++ b/share_extension/android/index.js @@ -5,8 +5,6 @@ import React, {PureComponent} from 'react'; import {Provider} from 'react-redux'; import {IntlProvider} from 'react-intl'; -import {Client4} from 'mattermost-redux/client'; - import {getTranslations} from 'app/i18n'; import {getCurrentLocale} from 'app/selectors/i18n'; import {store} from 'app/mattermost'; @@ -42,8 +40,6 @@ export default class ShareApp extends PureComponent { this.unsubscribeFromStore(); } - this.setCredentialsForClient(); - dispatch(extensionSelectTeamId(currentTeamId)); if (this.mounted) { @@ -52,16 +48,6 @@ export default class ShareApp extends PureComponent { } }; - setCredentialsForClient() { - const state = store.getState(); - const {credentials} = state.entities.general; - - if (credentials.token && credentials.url) { - Client4.setToken(credentials.token); - Client4.setUrl(credentials.url); - } - } - render() { if (!this.state.init) { return null;