Unverified Commit a9e61c5d authored by Djorkaeff Alexandre's avatar Djorkaeff Alexandre Committed by GitHub
Browse files

[FIX] HTTP Basic Auth (#1753)


Co-authored-by: default avatarDiego Mello <diegolmello@gmail.com>
parent 06cca9c6
......@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { View } from 'react-native';
import FastImage from 'react-native-fast-image';
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
import Touch from '../utils/touch';
const formatUrl = (url, baseUrl, uriSize, avatarAuthURLFragment) => (
......@@ -45,6 +46,7 @@ const Avatar = React.memo(({
style={avatarStyle}
source={{
uri,
headers: RocketChatSettings.customHeaders,
priority: FastImage.priority.high
}}
/>
......
import random from '../../utils/random';
import EventEmitter from '../../utils/events';
import fetch from '../../utils/fetch';
import Navigation from '../Navigation';
const ACTION_TYPES = {
......
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
import database from '../database';
import log from '../../utils/log';
import { headers } from '../../utils/fetch';
const uploadQueue = {};
......@@ -75,7 +75,10 @@ export function sendFileMessage(rid, fileInfo, tmid, server, user) {
xhr.setRequestHeader('X-Auth-Token', token);
xhr.setRequestHeader('X-User-Id', id);
xhr.setRequestHeader('User-Agent', headers['User-Agent']);
const { customHeaders } = RocketChatSettings;
Object.keys(customHeaders).forEach((key) => {
xhr.setRequestHeader(key, customHeaders[key]);
});
xhr.upload.onprogress = async({ total, loaded }) => {
try {
......
import { AsyncStorage, InteractionManager } from 'react-native';
import semver from 'semver';
import { Rocketchat as RocketchatClient, settings as RocketChatSettings } from '@rocket.chat/sdk';
import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
import RNUserDefaults from 'rn-user-defaults';
import { Q } from '@nozbe/watermelondb';
import * as FileSystem from 'expo-file-system';
......@@ -12,7 +12,7 @@ import database from './database';
import log from '../utils/log';
import { isIOS, getBundleId } from '../utils/deviceInfo';
import { extractHostname } from '../utils/server';
import fetch, { headers } from '../utils/fetch';
import fetch, { BASIC_AUTH_KEY } from '../utils/fetch';
import { setUser, setLoginServices, loginRequest } from '../actions/login';
import { disconnect, connectSuccess, connectRequest } from '../actions/connect';
......@@ -58,8 +58,6 @@ const MIN_ROCKETCHAT_VERSION = '0.70.0';
const STATUSES = ['offline', 'online', 'away', 'busy'];
RocketChatSettings.customHeaders = headers;
const RocketChat = {
TOKEN_KEY,
callJitsi,
......@@ -446,6 +444,7 @@ const RocketChat = {
await RNUserDefaults.clear('currentServer');
await RNUserDefaults.clear(TOKEN_KEY);
await RNUserDefaults.clear(`${ TOKEN_KEY }-${ server }`);
await RNUserDefaults.clear(`${ BASIC_AUTH_KEY }-${ server }`);
try {
const db = database.active;
......
......@@ -19,6 +19,7 @@ import log from '../utils/log';
import { extractHostname } from '../utils/server';
import I18n from '../i18n';
import { SERVERS, TOKEN, SERVER_URL } from '../constants/userDefaults';
import { BASIC_AUTH_KEY, setBasicAuth } from '../utils/fetch';
const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
try {
......@@ -89,6 +90,9 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch
}
}
const basicAuth = yield RNUserDefaults.get(`${ BASIC_AUTH_KEY }-${ server }`);
setBasicAuth(basicAuth);
if (user) {
yield RocketChat.connect({ server, user, logoutOnError: true });
yield put(setUser(user));
......
import { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
// this form is required by Rocket.Chat's parser in "app/statistics/server/lib/UAParserCustom.js"
export const headers = { 'User-Agent': `RC Mobile; ${ Platform.OS } ${ DeviceInfo.getSystemVersion() }; v${ DeviceInfo.getVersion() } (${ DeviceInfo.getBuildNumber() })` };
export const headers = {
'User-Agent': `RC Mobile; ${ Platform.OS } ${ DeviceInfo.getSystemVersion() }; v${ DeviceInfo.getVersion() } (${ DeviceInfo.getBuildNumber() })`
};
let _basicAuth;
export const setBasicAuth = (basicAuth) => {
_basicAuth = basicAuth;
if (basicAuth) {
RocketChatSettings.customHeaders = { ...RocketChatSettings.customHeaders, Authorization: `Basic ${ _basicAuth }` };
} else {
RocketChatSettings.customHeaders = headers;
}
};
export const BASIC_AUTH_KEY = 'BASIC_AUTH_KEY';
RocketChatSettings.customHeaders = headers;
export default (url, options = {}) => {
let customOptions = { ...options, headers };
let customOptions = { ...options, headers: RocketChatSettings.customHeaders };
if (options && options.headers) {
customOptions = { ...customOptions, headers: { ...options.headers, ...headers } };
customOptions = { ...customOptions, headers: { ...options.headers, ...customOptions.headers } };
}
return fetch(url, customOptions);
};
......@@ -9,6 +9,9 @@ import * as FileSystem from 'expo-file-system';
import DocumentPicker from 'react-native-document-picker';
import ActionSheet from 'react-native-action-sheet';
import isEqual from 'deep-equal';
import RNUserDefaults from 'rn-user-defaults';
import { encode } from 'base-64';
import parse from 'url-parse';
import { serverRequest } from '../actions/server';
import sharedStyles from './Styles';
......@@ -25,6 +28,7 @@ import { themes } from '../constants/colors';
import log from '../utils/log';
import { animateNextTransition } from '../utils/layoutAnimation';
import { withTheme } from '../theme';
import { setBasicAuth, BASIC_AUTH_KEY } from '../utils/fetch';
const styles = StyleSheet.create({
image: {
......@@ -148,7 +152,22 @@ class NewServerView extends React.Component {
if (text) {
Keyboard.dismiss();
connectServer(this.completeUrl(text), cert);
const server = this.completeUrl(text);
await this.basicAuth(server, text);
connectServer(server, cert);
}
}
basicAuth = async(server, text) => {
try {
const parsedUrl = parse(text, true);
if (parsedUrl.auth.length) {
const credentials = encode(parsedUrl.auth);
await RNUserDefaults.set(`${ BASIC_AUTH_KEY }-${ server }`, credentials);
setBasicAuth(credentials);
}
} catch {
// do nothing
}
}
......@@ -177,6 +196,11 @@ class NewServerView extends React.Component {
}
completeUrl = (url) => {
const parsedUrl = parse(url, true);
if (parsedUrl.auth.length) {
url = parsedUrl.host;
}
url = url && url.replace(/\s/g, '');
if (/^(\w|[0-9-_]){3,}$/.test(url)
......
......@@ -30,6 +30,7 @@
"@react-native-community/slider": "2.0.5",
"@rocket.chat/sdk": "1.0.0-alpha.41",
"@rocket.chat/ui-kit": "^0.2.0-alpha.25",
"base-64": "^0.1.0",
"bugsnag-react-native": "2.23.2",
"commonmark": "git+https://github.com/RocketChat/commonmark.js.git",
"commonmark-react-renderer": "git+https://github.com/RocketChat/commonmark-react-renderer.git",
......
......@@ -2748,7 +2748,7 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
 
base-64@0.1.0:
base-64@0.1.0, base-64@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb"
integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs=
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment