Commit f6609691 authored by jbuechele's avatar jbuechele
Browse files

Merge branch 'develop' into v2.8.0

# Conflicts:
#	android/app/build.gradle
#	ios/Podfile.lock
#	ios/RocketChatRN.xcodeproj/project.pbxproj
#	ios/RocketChatRN/Info.plist
#	ios/ShareRocketChatRN/Info.plist
#	yarn.lock
parents 2c8141d8 9d9553b0
......@@ -17,14 +17,15 @@ module.exports = {
legacyDecorators: true
}
},
plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel'],
plugins: ['react', 'jsx-a11y', 'import', 'react-native', '@babel', 'jest'],
env: {
browser: true,
commonjs: true,
es6: true,
node: true,
jquery: true,
mocha: true
mocha: true,
'jest/globals': true
},
rules: {
'import/extensions': [
......
......@@ -11,9 +11,12 @@ import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Principal;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import java.security.PrivateKey;
import javax.net.ssl.SSLContext;
......@@ -21,11 +24,12 @@ import javax.net.ssl.X509TrustManager;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import okhttp3.OkHttpClient;
import java.lang.InterruptedException;
import android.app.Activity;
import javax.net.ssl.KeyManager;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import com.RNFetchBlob.RNFetchBlob;
......@@ -52,8 +56,9 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC
public void apply(OkHttpClient.Builder builder) {
if (alias != null) {
SSLSocketFactory sslSocketFactory = getSSLFactory(alias);
X509TrustManager trustManager = getTrustManagerFactory();
if (sslSocketFactory != null) {
builder.sslSocketFactory(sslSocketFactory);
builder.sslSocketFactory(sslSocketFactory, trustManager);
}
}
}
......@@ -68,8 +73,9 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC
if (alias != null) {
SSLSocketFactory sslSocketFactory = getSSLFactory(alias);
X509TrustManager trustManager = getTrustManagerFactory();
if (sslSocketFactory != null) {
builder.sslSocketFactory(sslSocketFactory);
builder.sslSocketFactory(sslSocketFactory, trustManager);
}
}
......@@ -162,25 +168,9 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC
}
};
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return certChain;
}
}
};
final X509TrustManager trustManager = getTrustManagerFactory();
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(new KeyManager[]{keyManager}, trustAllCerts, new java.security.SecureRandom());
sslContext.init(new KeyManager[]{keyManager}, new TrustManager[]{trustManager}, new java.security.SecureRandom());
SSLContext.setDefault(sslContext);
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
......@@ -190,4 +180,19 @@ public class SSLPinningModule extends ReactContextBaseJavaModule implements KeyC
return null;
}
}
public static X509TrustManager getTrustManagerFactory() {
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
final X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
return trustManager;
} catch (Exception e) {
return null;
}
}
}
......@@ -2,8 +2,8 @@ const REQUEST = 'REQUEST';
const SUCCESS = 'SUCCESS';
const FAILURE = 'FAILURE';
const defaultTypes = [REQUEST, SUCCESS, FAILURE];
function createRequestTypes(base, types = defaultTypes) {
const res = {};
function createRequestTypes(base = {}, types = defaultTypes): Record<any, any> {
const res: Record<any, any> = {};
types.forEach(type => (res[type] = `${base}_${type}`));
return res;
}
......
import { SET_ACTIVE_USERS } from './actionsTypes';
export function setActiveUsers(activeUsers) {
return {
type: SET_ACTIVE_USERS,
activeUsers
};
}
import { Action } from 'redux';
import { IActiveUsers } from '../reducers/activeUsers';
import { SET_ACTIVE_USERS } from './actionsTypes';
export interface ISetActiveUsers extends Action {
activeUsers: IActiveUsers;
}
export type TActionActiveUsers = ISetActiveUsers;
export const setActiveUsers = (activeUsers: IActiveUsers): ISetActiveUsers => ({
type: SET_ACTIVE_USERS,
activeUsers
});
import { Action } from 'redux';
import { ISelectedUser } from '../reducers/selectedUsers';
import * as types from './actionsTypes';
export function addUser(user) {
type TUser = {
user: ISelectedUser;
};
type TAction = Action & TUser;
interface ISetLoading extends Action {
loading: boolean;
}
export type TActionSelectedUsers = TAction & ISetLoading;
export function addUser(user: ISelectedUser): TAction {
return {
type: types.SELECTED_USERS.ADD_USER,
user
};
}
export function removeUser(user) {
export function removeUser(user: ISelectedUser): TAction {
return {
type: types.SELECTED_USERS.REMOVE_USER,
user
};
}
export function reset() {
export function reset(): Action {
return {
type: types.SELECTED_USERS.RESET
};
}
export function setLoading(loading) {
export function setLoading(loading: boolean): ISetLoading {
return {
type: types.SELECTED_USERS.SET_LOADING,
loading
......
export const DISPLAY_MODE_CONDENSED = 'condensed';
export const DISPLAY_MODE_EXPANDED = 'expanded';
export enum DisplayMode {
Condensed = 'condensed',
Expanded = 'expanded'
}
export enum SortBy {
Alphabetical = 'alphabetical',
Activity = 'activity'
}
import React from 'react';
import { TouchableOpacity } from 'react-native';
import { isAndroid } from '../../utils/deviceInfo';
import Touch from '../../utils/touch';
// Taken from https://github.com/rgommezz/react-native-scroll-bottom-sheet#touchables
export const Button = isAndroid ? Touch : TouchableOpacity;
export const Button: typeof React.Component = isAndroid ? Touch : TouchableOpacity;
......@@ -5,6 +5,7 @@ import Touchable from 'react-native-platform-touchable';
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
import { avatarURL } from '../../utils/avatar';
import { SubscriptionType } from '../../definitions/ISubscription';
import Emoji from '../markdown/Emoji';
import { IAvatar } from './interfaces';
......@@ -27,8 +28,8 @@ const Avatar = React.memo(
text,
size = 25,
borderRadius = 4,
type = 'd'
}: Partial<IAvatar>) => {
type = SubscriptionType.DIRECT
}: IAvatar) => {
if ((!text && !avatar && !emoji && !rid) || !server) {
return null;
}
......
......@@ -7,17 +7,17 @@ import { getUserSelector } from '../../selectors/login';
import Avatar from './Avatar';
import { IAvatar } from './interfaces';
class AvatarContainer extends React.Component<Partial<IAvatar>, any> {
class AvatarContainer extends React.Component<IAvatar, any> {
private mounted: boolean;
private subscription!: any;
private subscription: any;
static defaultProps = {
text: '',
type: 'd'
};
constructor(props: Partial<IAvatar>) {
constructor(props: IAvatar) {
super(props);
this.mounted = false;
this.state = { avatarETag: '' };
......@@ -55,7 +55,7 @@ class AvatarContainer extends React.Component<Partial<IAvatar>, any> {
try {
if (this.isDirect) {
const { text } = this.props;
const [user] = await usersCollection.query(Q.where('username', text!)).fetch();
const [user] = await usersCollection.query(Q.where('username', text)).fetch();
record = user;
} else {
const { rid } = this.props;
......@@ -82,7 +82,7 @@ class AvatarContainer extends React.Component<Partial<IAvatar>, any> {
render() {
const { avatarETag } = this.state;
const { serverVersion } = this.props;
return <Avatar avatarETag={avatarETag} serverVersion={serverVersion} {...this.props} />;
return <Avatar {...this.props} avatarETag={avatarETag} serverVersion={serverVersion} />;
}
}
......
export interface IAvatar {
server: string;
style: any;
server?: string;
style?: any;
text: string;
avatar: string;
emoji: string;
size: number;
borderRadius: number;
type: string;
children: JSX.Element;
user: {
id: string;
token: string;
avatar?: string;
emoji?: string;
size?: number;
borderRadius?: number;
type?: string;
children?: JSX.Element;
user?: {
id?: string;
token?: string;
};
theme: string;
onPress(): void;
getCustomEmoji(): any;
avatarETag: string;
isStatic: boolean | string;
rid: string;
blockUnauthenticatedAccess: boolean;
serverVersion: string;
theme?: string;
onPress?: () => void;
getCustomEmoji?: () => any;
avatarETag?: string;
isStatic?: boolean | string;
rid?: string;
blockUnauthenticatedAccess?: boolean;
serverVersion?: string;
}
......@@ -305,8 +305,6 @@ const MessageActions = React.memo(
};
const handleDelete = (message: any) => {
// TODO - migrate this function for ts when fix the lint erros
// @ts-ignore
showConfirmationAlert({
message: I18n.t('You_will_not_be_able_to_recover_this_message'),
confirmationText: I18n.t('Delete'),
......
......@@ -7,28 +7,28 @@ import Touch from '../../../utils/touch';
import { CustomIcon } from '../../../lib/Icons';
interface IPasscodeButton {
text: string;
icon: string;
text?: string;
icon?: string;
theme: string;
disabled: boolean;
onPress: Function;
disabled?: boolean;
onPress?: Function;
}
const Button = React.memo(({ text, disabled, theme, onPress, icon }: Partial<IPasscodeButton>) => {
const press = () => onPress && onPress(text!);
const Button = React.memo(({ text, disabled, theme, onPress, icon }: IPasscodeButton) => {
const press = () => onPress && onPress(text);
return (
<Touch
style={[styles.buttonView, { backgroundColor: 'transparent' }]}
underlayColor={themes[theme!].passcodeButtonActive}
rippleColor={themes[theme!].passcodeButtonActive}
underlayColor={themes[theme].passcodeButtonActive}
rippleColor={themes[theme].passcodeButtonActive}
enabled={!disabled}
theme={theme}
onPress={press}>
{icon ? (
<CustomIcon name={icon} size={36} color={themes[theme!].passcodePrimary} />
<CustomIcon name={icon} size={36} color={themes[theme].passcodePrimary} />
) : (
<Text style={[styles.buttonText, { color: themes[theme!].passcodePrimary }]}>{text}</Text>
<Text style={[styles.buttonText, { color: themes[theme].passcodePrimary }]}>{text}</Text>
)}
</Touch>
);
......
......@@ -13,6 +13,7 @@ import { themes } from '../../constants/colors';
import MessageContext from './Context';
import { fileDownloadAndPreview } from '../../utils/fileDownload';
import { formatAttachmentUrl } from '../../lib/utils';
import { IAttachment } from '../../definitions/IAttachment';
import RCActivityIndicator from '../ActivityIndicator';
const styles = StyleSheet.create({
......@@ -90,43 +91,26 @@ const styles = StyleSheet.create({
}
});
interface IMessageReplyAttachment {
author_name: string;
message_link: string;
ts: string;
text: string;
title: string;
short: boolean;
value: string;
title_link: string;
author_link: string;
type: string;
color: string;
description: string;
fields: IMessageReplyAttachment[];
thumb_url: string;
}
interface IMessageTitle {
attachment: Partial<IMessageReplyAttachment>;
attachment: IAttachment;
timeFormat: string;
theme: string;
}
interface IMessageDescription {
attachment: Partial<IMessageReplyAttachment>;
attachment: IAttachment;
getCustomEmoji: Function;
theme: string;
}
interface IMessageFields {
attachment: Partial<IMessageReplyAttachment>;
attachment: IAttachment;
theme: string;
getCustomEmoji: Function;
}
interface IMessageReply {
attachment: IMessageReplyAttachment;
attachment: IAttachment;
timeFormat: string;
index: number;
theme: string;
......@@ -198,7 +182,7 @@ const Fields = React.memo(
<Text style={[styles.fieldTitle, { color: themes[theme].bodyText }]}>{field.title}</Text>
{/* @ts-ignore*/}
<Markdown
msg={field.value}
msg={field.value!}
baseUrl={baseUrl}
username={user.username}
getCustomEmoji={getCustomEmoji}
......
......@@ -13,6 +13,7 @@ import { fileDownload } from '../../utils/fileDownload';
import EventEmitter from '../../utils/events';
import { LISTENER } from '../Toast';
import I18n from '../../i18n';
import { IAttachment } from '../../definitions/IAttachment';
import RCActivityIndicator from '../ActivityIndicator';
const SUPPORTED_TYPES = ['video/quicktime', 'video/mp4', ...(isIOS ? [] : ['video/3gp', 'video/mkv'])];
......@@ -30,14 +31,7 @@ const styles = StyleSheet.create({
});
interface IMessageVideo {
file: {
title: string;
title_link: string;
type: string;
video_type: string;
video_url: string;
description: string;
};
file: IAttachment;
showAttachment: Function;
getCustomEmoji: Function;
theme: string;
......
......@@ -84,7 +84,7 @@ export interface IMessageContent {
export interface IMessageDiscussion {
msg: string;
dcount: number;
dlm: string;
dlm: Date;
theme: string;
}
......
export interface IAttachment {
ts: Date;
title: string;
type: string;
description: string;
......@@ -7,4 +8,18 @@ export interface IAttachment {
image_type?: string;
video_url?: string;
video_type?: string;
title_link_download?: boolean;
fields?: IAttachment[];
image_dimensions?: { width?: number; height?: number };
image_preview?: string;
image_size?: number;
author_name?: string;
author_icon?: string;
message_link?: string;
text?: string;
short?: boolean;
value?: string;
author_link?: string;
color?: string;
thumb_url?: string;
}
export interface ICommand {
event: {
input: string;
modifierFlags: number;
};
}
import Model from '@nozbe/watermelondb/Model';
export interface ICustomEmoji {
name?: string;
aliases?: string;
extension: string;
_updatedAt: Date;
}
export type TCustomEmojiModel = ICustomEmoji & Model;
Supports Markdown
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