[IMPROVEMENT] Share credentials with Rocket.Chat.iOS (#982)
* ✨ Create user table * ✨ Introduce user table * 🔥 Remove unused table * ➕ Add userdefaults to storage data * 💚 Fix android build * ✨ Get credentials from iOS native client * 🔥 Remove unused code * ⏪ Revert sign xcode * 🐛 Fix first login-logout * 🎨 Use constants to UserDefaults Keys * 🐛 Fix clear server-user-info on logout * 🐛 Fix filter null value * 🚑 Remove user object in logout * ✨ Fix get servers from native-client * 🚑 Fix error on change server
This commit is contained in:
parent
315d19d37a
commit
255ea84599
|
@ -0,0 +1,6 @@
|
||||||
|
export const SERVERS = 'kServers';
|
||||||
|
export const TOKEN = 'kAuthToken';
|
||||||
|
export const USER_ID = 'kUserId';
|
||||||
|
export const SERVER_URL = 'kAuthServerURL';
|
||||||
|
export const SERVER_NAME = 'kServerName';
|
||||||
|
export const SERVER_ICON = 'kServerIconURL';
|
|
@ -4,6 +4,20 @@ import Realm from 'realm';
|
||||||
// Realm.clearTestState();
|
// Realm.clearTestState();
|
||||||
// AsyncStorage.clear();
|
// AsyncStorage.clear();
|
||||||
|
|
||||||
|
const userSchema = {
|
||||||
|
name: 'user',
|
||||||
|
primaryKey: 'id',
|
||||||
|
properties: {
|
||||||
|
id: 'string',
|
||||||
|
token: { type: 'string', optional: true },
|
||||||
|
username: { type: 'string', optional: true },
|
||||||
|
name: { type: 'string', optional: true },
|
||||||
|
language: { type: 'string', optional: true },
|
||||||
|
status: { type: 'string', optional: true },
|
||||||
|
roles: { type: 'string[]', optional: true }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const serversSchema = {
|
const serversSchema = {
|
||||||
name: 'servers',
|
name: 'servers',
|
||||||
primaryKey: 'id',
|
primaryKey: 'id',
|
||||||
|
@ -370,6 +384,7 @@ class DB {
|
||||||
serversDB: new Realm({
|
serversDB: new Realm({
|
||||||
path: 'default.realm',
|
path: 'default.realm',
|
||||||
schema: [
|
schema: [
|
||||||
|
userSchema,
|
||||||
serversSchema
|
serversSchema
|
||||||
],
|
],
|
||||||
schemaVersion: 8,
|
schemaVersion: 8,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AsyncStorage, InteractionManager } from 'react-native';
|
import { AsyncStorage, InteractionManager } from 'react-native';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
|
import { Rocketchat as RocketchatClient } from '@rocket.chat/sdk';
|
||||||
|
import RNUserDefaults from 'rn-user-defaults';
|
||||||
|
|
||||||
import reduxStore from './createStore';
|
import reduxStore from './createStore';
|
||||||
import defaultSettings from '../constants/settings';
|
import defaultSettings from '../constants/settings';
|
||||||
|
@ -36,6 +37,7 @@ import sendMessage, { getMessage, sendMessageCall } from './methods/sendMessage'
|
||||||
import { sendFileMessage, cancelUpload, isUploadActive } from './methods/sendFileMessage';
|
import { sendFileMessage, cancelUpload, isUploadActive } from './methods/sendFileMessage';
|
||||||
|
|
||||||
import { getDeviceToken } from '../notifications/push';
|
import { getDeviceToken } from '../notifications/push';
|
||||||
|
import { SERVERS, SERVER_URL } from '../constants/userDefaults';
|
||||||
|
|
||||||
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
const TOKEN_KEY = 'reactnativemeteor_usertoken';
|
||||||
const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY';
|
const SORT_PREFS_KEY = 'RC_SORT_PREFS_KEY';
|
||||||
|
@ -58,9 +60,9 @@ const RocketChat = {
|
||||||
},
|
},
|
||||||
async getUserToken() {
|
async getUserToken() {
|
||||||
try {
|
try {
|
||||||
return await AsyncStorage.getItem(TOKEN_KEY);
|
return await RNUserDefaults.get(TOKEN_KEY);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`AsyncStorage error: ${ error.message }`);
|
console.warn(`RNUserDefaults error: ${ error.message }`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getServerInfo(server) {
|
async getServerInfo(server) {
|
||||||
|
@ -321,10 +323,26 @@ const RocketChat = {
|
||||||
}
|
}
|
||||||
this.sdk = null;
|
this.sdk = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const servers = await RNUserDefaults.objectForKey(SERVERS);
|
||||||
|
await RNUserDefaults.setObjectForKey(SERVERS, servers && servers.filter(srv => srv[SERVER_URL] !== server));
|
||||||
|
} catch (error) {
|
||||||
|
console.log('logout_rn_user_defaults', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { serversDB } = database.databases;
|
||||||
|
|
||||||
|
const userId = await RNUserDefaults.get(`${ TOKEN_KEY }-${ server }`);
|
||||||
|
|
||||||
|
serversDB.write(() => {
|
||||||
|
const user = serversDB.objectForPrimaryKey('user', userId);
|
||||||
|
serversDB.delete(user);
|
||||||
|
});
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
AsyncStorage.removeItem('currentServer'),
|
RNUserDefaults.clear('currentServer'),
|
||||||
AsyncStorage.removeItem(TOKEN_KEY),
|
RNUserDefaults.clear(TOKEN_KEY),
|
||||||
AsyncStorage.removeItem(`${ TOKEN_KEY }-${ server }`)
|
RNUserDefaults.clear(`${ TOKEN_KEY }-${ server }`)
|
||||||
]).catch(error => console.log(error));
|
]).catch(error => console.log(error));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { AsyncStorage } from 'react-native';
|
|
||||||
import { delay } from 'redux-saga';
|
import { delay } from 'redux-saga';
|
||||||
import {
|
import {
|
||||||
takeLatest, take, select, put, all
|
takeLatest, take, select, put, all
|
||||||
} from 'redux-saga/effects';
|
} from 'redux-saga/effects';
|
||||||
|
import RNUserDefaults from 'rn-user-defaults';
|
||||||
|
|
||||||
import Navigation from '../lib/Navigation';
|
import Navigation from '../lib/Navigation';
|
||||||
import * as types from '../actions/actionsTypes';
|
import * as types from '../actions/actionsTypes';
|
||||||
|
@ -43,8 +43,8 @@ const handleOpen = function* handleOpen({ params }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [server, user] = yield all([
|
const [server, user] = yield all([
|
||||||
AsyncStorage.getItem('currentServer'),
|
RNUserDefaults.get('currentServer'),
|
||||||
AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ host }`)
|
RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ host }`)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// TODO: needs better test
|
// TODO: needs better test
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { AsyncStorage } from 'react-native';
|
|
||||||
import { put, takeLatest, all } from 'redux-saga/effects';
|
import { put, takeLatest, all } from 'redux-saga/effects';
|
||||||
import SplashScreen from 'react-native-splash-screen';
|
import SplashScreen from 'react-native-splash-screen';
|
||||||
|
import RNUserDefaults from 'rn-user-defaults';
|
||||||
|
|
||||||
import * as actions from '../actions';
|
import * as actions from '../actions';
|
||||||
import { selectServerRequest } from '../actions/server';
|
import { selectServerRequest } from '../actions/server';
|
||||||
|
@ -11,14 +11,46 @@ import RocketChat from '../lib/rocketchat';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
import Navigation from '../lib/Navigation';
|
import Navigation from '../lib/Navigation';
|
||||||
import database from '../lib/realm';
|
import database from '../lib/realm';
|
||||||
|
import {
|
||||||
|
SERVERS, SERVER_ICON, SERVER_NAME, SERVER_URL, TOKEN, USER_ID
|
||||||
|
} from '../constants/userDefaults';
|
||||||
|
|
||||||
const restore = function* restore() {
|
const restore = function* restore() {
|
||||||
try {
|
try {
|
||||||
const { token, server } = yield all({
|
yield RNUserDefaults.setName('group.ios.chat.rocket');
|
||||||
token: AsyncStorage.getItem(RocketChat.TOKEN_KEY),
|
|
||||||
server: AsyncStorage.getItem('currentServer')
|
let { token, server } = yield all({
|
||||||
|
token: RNUserDefaults.get(RocketChat.TOKEN_KEY),
|
||||||
|
server: RNUserDefaults.get('currentServer')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// get native credentials
|
||||||
|
const { serversDB } = database.databases;
|
||||||
|
const servers = yield RNUserDefaults.objectForKey(SERVERS);
|
||||||
|
if (servers) {
|
||||||
|
serversDB.write(() => {
|
||||||
|
servers.forEach(async(serverItem) => {
|
||||||
|
const serverInfo = {
|
||||||
|
id: serverItem[SERVER_URL],
|
||||||
|
name: serverItem[SERVER_NAME],
|
||||||
|
iconURL: serverItem[SERVER_ICON]
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
serversDB.create('servers', serverInfo, true);
|
||||||
|
await RNUserDefaults.set(`${ RocketChat.TOKEN_KEY }-${ serverInfo.id }`, serverItem[USER_ID]);
|
||||||
|
} catch (e) {
|
||||||
|
log('err_create_servers', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not have current
|
||||||
|
if (servers.length !== 0 && (!token || !server)) {
|
||||||
|
server = servers[0][SERVER_URL];
|
||||||
|
token = servers[0][TOKEN];
|
||||||
|
}
|
||||||
|
|
||||||
const sortPreferences = yield RocketChat.getSortPreferences();
|
const sortPreferences = yield RocketChat.getSortPreferences();
|
||||||
yield put(setAllPreferences(sortPreferences));
|
yield put(setAllPreferences(sortPreferences));
|
||||||
|
|
||||||
|
@ -27,8 +59,8 @@ const restore = function* restore() {
|
||||||
|
|
||||||
if (!token || !server) {
|
if (!token || !server) {
|
||||||
yield all([
|
yield all([
|
||||||
AsyncStorage.removeItem(RocketChat.TOKEN_KEY),
|
RNUserDefaults.clear(RocketChat.TOKEN_KEY),
|
||||||
AsyncStorage.removeItem('currentServer')
|
RNUserDefaults.clear('currentServer')
|
||||||
]);
|
]);
|
||||||
yield put(actions.appStart('outside'));
|
yield put(actions.appStart('outside'));
|
||||||
} else if (server) {
|
} else if (server) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { AsyncStorage } from 'react-native';
|
|
||||||
import {
|
import {
|
||||||
put, call, takeLatest, select, take, fork, cancel
|
put, call, takeLatest, select, take, fork, cancel
|
||||||
} from 'redux-saga/effects';
|
} from 'redux-saga/effects';
|
||||||
|
import RNUserDefaults from 'rn-user-defaults';
|
||||||
|
|
||||||
import * as types from '../actions/actionsTypes';
|
import * as types from '../actions/actionsTypes';
|
||||||
import { appStart } from '../actions';
|
import { appStart } from '../actions';
|
||||||
|
@ -60,7 +60,7 @@ const fetchUserPresence = function* fetchUserPresence() {
|
||||||
const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
try {
|
try {
|
||||||
const adding = yield select(state => state.server.adding);
|
const adding = yield select(state => state.server.adding);
|
||||||
yield AsyncStorage.setItem(RocketChat.TOKEN_KEY, user.token);
|
yield RNUserDefaults.set(RocketChat.TOKEN_KEY, user.token);
|
||||||
|
|
||||||
const server = yield select(getServer);
|
const server = yield select(getServer);
|
||||||
yield put(roomsRequest());
|
yield put(roomsRequest());
|
||||||
|
@ -72,7 +72,17 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
yield fork(fetchUserPresence);
|
yield fork(fetchUserPresence);
|
||||||
|
|
||||||
I18n.locale = user.language;
|
I18n.locale = user.language;
|
||||||
yield AsyncStorage.setItem(`${ RocketChat.TOKEN_KEY }-${ server }`, JSON.stringify(user));
|
|
||||||
|
const { serversDB } = database.databases;
|
||||||
|
serversDB.write(() => {
|
||||||
|
try {
|
||||||
|
serversDB.create('user', user, true);
|
||||||
|
} catch (e) {
|
||||||
|
log('err_set_user_token', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
yield RNUserDefaults.set(`${ RocketChat.TOKEN_KEY }-${ server }`, user.id);
|
||||||
yield put(setUser(user));
|
yield put(setUser(user));
|
||||||
EventEmitter.emit('connected');
|
EventEmitter.emit('connected');
|
||||||
|
|
||||||
|
@ -105,7 +115,7 @@ const handleLogout = function* handleLogout() {
|
||||||
// see if there's other logged in servers and selects first one
|
// see if there's other logged in servers and selects first one
|
||||||
if (servers.length > 0) {
|
if (servers.length > 0) {
|
||||||
const newServer = servers[0].id;
|
const newServer = servers[0].id;
|
||||||
const token = yield AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ newServer }`);
|
const token = yield RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ newServer }`);
|
||||||
if (token) {
|
if (token) {
|
||||||
return yield put(selectServerRequest(newServer));
|
return yield put(selectServerRequest(newServer));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import {
|
import {
|
||||||
put, take, takeLatest, fork, cancel, race
|
put, take, takeLatest, fork, cancel, race
|
||||||
} from 'redux-saga/effects';
|
} from 'redux-saga/effects';
|
||||||
import { AsyncStorage, Alert } from 'react-native';
|
import { Alert } from 'react-native';
|
||||||
|
import RNUserDefaults from 'rn-user-defaults';
|
||||||
|
|
||||||
import Navigation from '../lib/Navigation';
|
import Navigation from '../lib/Navigation';
|
||||||
import { SERVER } from '../actions/actionsTypes';
|
import { SERVER } from '../actions/actionsTypes';
|
||||||
|
@ -14,6 +15,7 @@ import RocketChat from '../lib/rocketchat';
|
||||||
import database from '../lib/realm';
|
import database from '../lib/realm';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
|
import { SERVERS, TOKEN, SERVER_URL } from '../constants/userDefaults';
|
||||||
|
|
||||||
const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
|
const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
|
||||||
try {
|
try {
|
||||||
|
@ -38,13 +40,21 @@ const getServerInfo = function* getServerInfo({ server, raiseError = true }) {
|
||||||
|
|
||||||
const handleSelectServer = function* handleSelectServer({ server, version, fetchVersion }) {
|
const handleSelectServer = function* handleSelectServer({ server, version, fetchVersion }) {
|
||||||
try {
|
try {
|
||||||
yield AsyncStorage.setItem('currentServer', server);
|
const { serversDB } = database.databases;
|
||||||
const userStringified = yield AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
|
||||||
|
|
||||||
if (userStringified) {
|
yield RNUserDefaults.set('currentServer', server);
|
||||||
const user = JSON.parse(userStringified);
|
const userId = yield RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||||
yield RocketChat.connect({ server, user });
|
const user = userId && serversDB.objectForPrimaryKey('user', userId);
|
||||||
yield put(setUser(user));
|
|
||||||
|
const servers = yield RNUserDefaults.objectForKey(SERVERS);
|
||||||
|
const userCredentials = servers && servers.find(srv => srv[SERVER_URL] === server);
|
||||||
|
const userLogin = userCredentials && {
|
||||||
|
token: userCredentials[TOKEN]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (user || userLogin) {
|
||||||
|
yield RocketChat.connect({ server, user: user || userLogin });
|
||||||
|
yield put(setUser(user || userLogin));
|
||||||
yield put(actions.appStart('inside'));
|
yield put(actions.appStart('inside'));
|
||||||
} else {
|
} else {
|
||||||
yield RocketChat.connect({ server });
|
yield RocketChat.connect({ server });
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import {
|
||||||
View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image, AsyncStorage
|
View, Text, Animated, Easing, TouchableWithoutFeedback, TouchableOpacity, FlatList, Image
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import equal from 'deep-equal';
|
import equal from 'deep-equal';
|
||||||
import { withNavigation } from 'react-navigation';
|
import { withNavigation } from 'react-navigation';
|
||||||
|
import RNUserDefaults from 'rn-user-defaults';
|
||||||
|
|
||||||
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
|
import { toggleServerDropdown as toggleServerDropdownAction } from '../../actions/rooms';
|
||||||
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
|
||||||
|
@ -124,8 +125,8 @@ class ServerDropdown extends Component {
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
if (currentServer !== server) {
|
if (currentServer !== server) {
|
||||||
const token = await AsyncStorage.getItem(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
const userId = await RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||||
if (!token) {
|
if (!userId) {
|
||||||
appStart();
|
appStart();
|
||||||
this.newServerTimeout = setTimeout(() => {
|
this.newServerTimeout = setTimeout(() => {
|
||||||
EventEmitter.emit('NewServer', { server });
|
EventEmitter.emit('NewServer', { server });
|
||||||
|
|
|
@ -39,6 +39,7 @@ const keyExtractor = item => item.rid;
|
||||||
|
|
||||||
@connect(state => ({
|
@connect(state => ({
|
||||||
userId: state.login.user && state.login.user.id,
|
userId: state.login.user && state.login.user.id,
|
||||||
|
isAuthenticated: state.login.isAuthenticated,
|
||||||
server: state.server.server,
|
server: state.server.server,
|
||||||
baseUrl: state.settings.baseUrl || state.server ? state.server.server : '',
|
baseUrl: state.settings.baseUrl || state.server ? state.server.server : '',
|
||||||
searchText: state.rooms.searchText,
|
searchText: state.rooms.searchText,
|
||||||
|
@ -111,7 +112,8 @@ export default class RoomsListView extends React.Component {
|
||||||
openSearchHeader: PropTypes.func,
|
openSearchHeader: PropTypes.func,
|
||||||
closeSearchHeader: PropTypes.func,
|
closeSearchHeader: PropTypes.func,
|
||||||
appStart: PropTypes.func,
|
appStart: PropTypes.func,
|
||||||
roomsRequest: PropTypes.func
|
roomsRequest: PropTypes.func,
|
||||||
|
isAuthenticated: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -187,7 +189,7 @@ export default class RoomsListView extends React.Component {
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
const {
|
const {
|
||||||
sortBy, groupByType, showFavorites, showUnread, appState, roomsRequest
|
sortBy, groupByType, showFavorites, showUnread, appState, roomsRequest, isAuthenticated
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!(
|
if (!(
|
||||||
|
@ -197,7 +199,7 @@ export default class RoomsListView extends React.Component {
|
||||||
&& (prevProps.showUnread === showUnread)
|
&& (prevProps.showUnread === showUnread)
|
||||||
)) {
|
)) {
|
||||||
this.getSubscriptions();
|
this.getSubscriptions();
|
||||||
} else if (appState === 'foreground' && appState !== prevProps.appState) {
|
} else if (appState === 'foreground' && appState !== prevProps.appState && isAuthenticated) {
|
||||||
roomsRequest();
|
roomsRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ export default class Sidebar extends Component {
|
||||||
const permissionsFiltered = database.objects('permissions')
|
const permissionsFiltered = database.objects('permissions')
|
||||||
.filter(permission => permissions.includes(permission._id));
|
.filter(permission => permissions.includes(permission._id));
|
||||||
return permissionsFiltered.reduce((result, permission) => (
|
return permissionsFiltered.reduce((result, permission) => (
|
||||||
result || permission.roles.some(r => roles.includes(r))),
|
result || permission.roles.some(r => roles.indexOf(r) !== -1)),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
|
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
|
||||||
|
1E02221122B2F76B00001862 /* libRNUserDefaults.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E02220D22B2F76400001862 /* libRNUserDefaults.a */; };
|
||||||
24A2AEF2383D44B586D31C01 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 06BB44DD4855498082A744AD /* libz.tbd */; };
|
24A2AEF2383D44B586D31C01 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 06BB44DD4855498082A744AD /* libz.tbd */; };
|
||||||
38CEA0ED468E49CFABCD82FD /* libRNFirebase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A36F9982B71E4662AA8DEB77 /* libRNFirebase.a */; };
|
38CEA0ED468E49CFABCD82FD /* libRNFirebase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A36F9982B71E4662AA8DEB77 /* libRNFirebase.a */; };
|
||||||
50046CB6BDA69B9232CF66D9 /* libPods-RocketChatRN.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C235DC7B31A4D1578EDEF219 /* libPods-RocketChatRN.a */; };
|
50046CB6BDA69B9232CF66D9 /* libPods-RocketChatRN.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C235DC7B31A4D1578EDEF219 /* libPods-RocketChatRN.a */; };
|
||||||
|
@ -99,6 +100,13 @@
|
||||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||||
remoteInfo = React;
|
remoteInfo = React;
|
||||||
};
|
};
|
||||||
|
1E02220C22B2F76400001862 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 1E0221D522B2F76300001862 /* RNUserDefaults.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||||
|
remoteInfo = RNUserDefaults;
|
||||||
|
};
|
||||||
3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||||
|
@ -452,6 +460,7 @@
|
||||||
1845C223DA364898A8400573 /* FastImage.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = FastImage.xcodeproj; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = "<group>"; };
|
1845C223DA364898A8400573 /* FastImage.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = FastImage.xcodeproj; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = "<group>"; };
|
||||||
1A34D902CC074FF1BCC7DB48 /* libimageCropPicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libimageCropPicker.a; sourceTree = "<group>"; };
|
1A34D902CC074FF1BCC7DB48 /* libimageCropPicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libimageCropPicker.a; sourceTree = "<group>"; };
|
||||||
1D3BB00B9ABF44EA9BD71318 /* libSafariViewManager.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSafariViewManager.a; sourceTree = "<group>"; };
|
1D3BB00B9ABF44EA9BD71318 /* libSafariViewManager.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libSafariViewManager.a; sourceTree = "<group>"; };
|
||||||
|
1E0221D522B2F76300001862 /* RNUserDefaults.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNUserDefaults.xcodeproj; path = "../node_modules/rn-user-defaults/ios/RNUserDefaults.xcodeproj"; sourceTree = "<group>"; };
|
||||||
20CE3E407E0D4D9E8C9885F2 /* libRCTVideo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTVideo.a; sourceTree = "<group>"; };
|
20CE3E407E0D4D9E8C9885F2 /* libRCTVideo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTVideo.a; sourceTree = "<group>"; };
|
||||||
22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
|
22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
|
||||||
22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNI18n.xcodeproj; path = "../node_modules/react-native-i18n/ios/RNI18n.xcodeproj"; sourceTree = "<group>"; };
|
22D3971EAF2E4660B4FAB3DD /* RNI18n.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNI18n.xcodeproj; path = "../node_modules/react-native-i18n/ios/RNI18n.xcodeproj"; sourceTree = "<group>"; };
|
||||||
|
@ -492,6 +501,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
1E02221122B2F76B00001862 /* libRNUserDefaults.a in Frameworks */,
|
||||||
7ACD4897222860DE00442C55 /* JavaScriptCore.framework in Frameworks */,
|
7ACD4897222860DE00442C55 /* JavaScriptCore.framework in Frameworks */,
|
||||||
7A8DEB5A20ED0BEC00C5DCE4 /* libRNNotifications.a in Frameworks */,
|
7A8DEB5A20ED0BEC00C5DCE4 /* libRNNotifications.a in Frameworks */,
|
||||||
B8971BB2202A093B0000D245 /* libKeyboardTrackingView.a in Frameworks */,
|
B8971BB2202A093B0000D245 /* libKeyboardTrackingView.a in Frameworks */,
|
||||||
|
@ -626,6 +636,14 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
1E0221D622B2F76300001862 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1E02220D22B2F76400001862 /* libRNUserDefaults.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
22CA7F59107E0C79C2506C7C /* Pods */ = {
|
22CA7F59107E0C79C2506C7C /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -731,6 +749,7 @@
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
1E0221D522B2F76300001862 /* RNUserDefaults.xcodeproj */,
|
||||||
7A8DEB1B20ED0BDE00C5DCE4 /* RNNotifications.xcodeproj */,
|
7A8DEB1B20ED0BDE00C5DCE4 /* RNNotifications.xcodeproj */,
|
||||||
B8971BAC202A091D0000D245 /* KeyboardTrackingView.xcodeproj */,
|
B8971BAC202A091D0000D245 /* KeyboardTrackingView.xcodeproj */,
|
||||||
7A430E1620238C01008F55BC /* RCTCustomInputController.xcodeproj */,
|
7A430E1620238C01008F55BC /* RCTCustomInputController.xcodeproj */,
|
||||||
|
@ -1016,6 +1035,10 @@
|
||||||
ProductGroup = 7A8DEB1C20ED0BDE00C5DCE4 /* Products */;
|
ProductGroup = 7A8DEB1C20ED0BDE00C5DCE4 /* Products */;
|
||||||
ProjectRef = 7A8DEB1B20ED0BDE00C5DCE4 /* RNNotifications.xcodeproj */;
|
ProjectRef = 7A8DEB1B20ED0BDE00C5DCE4 /* RNNotifications.xcodeproj */;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 1E0221D622B2F76300001862 /* Products */;
|
||||||
|
ProjectRef = 1E0221D522B2F76300001862 /* RNUserDefaults.xcodeproj */;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ProductGroup = B8E79A8A1F3CCC6C005B464F /* Products */;
|
ProductGroup = B8E79A8A1F3CCC6C005B464F /* Products */;
|
||||||
ProjectRef = 22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */;
|
ProjectRef = 22A8B76C8EBA443BB97CE82D /* RNVectorIcons.xcodeproj */;
|
||||||
|
@ -1085,6 +1108,13 @@
|
||||||
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
|
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
1E02220D22B2F76400001862 /* libRNUserDefaults.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRNUserDefaults.a;
|
||||||
|
remoteRef = 1E02220C22B2F76400001862 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
|
3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = archive.ar;
|
fileType = archive.ar;
|
||||||
|
|
|
@ -8,5 +8,9 @@
|
||||||
<array>
|
<array>
|
||||||
<string>applinks:go.rocket.chat</string>
|
<string>applinks:go.rocket.chat</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.ios.chat.rocket</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
"redux-saga": "^0.16.2",
|
"redux-saga": "^0.16.2",
|
||||||
"remove-markdown": "^0.3.0",
|
"remove-markdown": "^0.3.0",
|
||||||
"rn-fetch-blob": "^0.10.15",
|
"rn-fetch-blob": "^0.10.15",
|
||||||
|
"rn-user-defaults": "^1.3.4",
|
||||||
"semver": "6.0.0",
|
"semver": "6.0.0",
|
||||||
"snyk": "^1.156.0",
|
"snyk": "^1.156.0",
|
||||||
"strip-ansi": "5.2.0"
|
"strip-ansi": "5.2.0"
|
||||||
|
|
|
@ -12550,6 +12550,11 @@ rn-fetch-blob@^0.10.15:
|
||||||
base-64 "0.1.0"
|
base-64 "0.1.0"
|
||||||
glob "7.0.6"
|
glob "7.0.6"
|
||||||
|
|
||||||
|
rn-user-defaults@^1.3.4:
|
||||||
|
version "1.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/rn-user-defaults/-/rn-user-defaults-1.3.4.tgz#1fbdd1bf29d9f853918dca5219e45db54d19fe37"
|
||||||
|
integrity sha512-CnzZbq3Q1VQUr6wKl9Z48eKmOzu+6dMcl2wN0ty+sBnpUyIqFvv3CMzYzb26v1qK8z7q/PcMr75shFHcrJH9WA==
|
||||||
|
|
||||||
rsvp@^3.3.3:
|
rsvp@^3.3.3:
|
||||||
version "3.6.2"
|
version "3.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
|
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
|
||||||
|
|
Loading…
Reference in New Issue