Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/containers/MessageActions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ const MessageActions = React.memo(forwardRef(({
const handleDelete = (message) => {
showConfirmationAlert({
message: I18n.t('You_will_not_be_able_to_recover_this_message'),
callToAction: I18n.t('Delete'),
confirmationText: I18n.t('Delete'),
onPress: async() => {
try {
logEvent(events.ROOM_MSG_ACTION_DELETE);
Expand Down
4 changes: 4 additions & 0 deletions app/i18n/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ export default {
Channels: 'Channels',
Chats: 'Chats',
Call_already_ended: 'Call already ended!',
Clear_cookies_alert: 'Do you want to clear all cookies?',
Clear_cookies_desc: 'This action will clear all login cookies, allowing you to login into other accounts.',
Clear_cookies_yes: 'Yes, clear cookies',
Clear_cookies_no: 'No, keep cookies',
Click_to_join: 'Click to Join!',
Close: 'Close',
Close_emoji_selector: 'Close emoji selector',
Expand Down
4 changes: 4 additions & 0 deletions app/i18n/locales/pt-BR.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ export default {
Change_language_loading: 'Alterando idioma.',
Call_already_ended: 'A chamada já terminou!',
Clear_cache_loading: 'Limpando cache.',
Clear_cookies_alert: 'Você quer limpar seus cookies?',
Clear_cookies_desc: 'Esta ação limpará todos os cookies de login permitindo que você faça login em outras contas.',
Clear_cookies_yes: 'Sim, limpar cookies',
Clear_cookies_no: 'Não, manter cookies',
Click_to_join: 'Clique para participar!',
Close: 'Fechar',
Close_emoji_selector: 'Fechar seletor de emojis',
Expand Down
2 changes: 2 additions & 0 deletions app/lib/database/model/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ export default class User extends Model {

@field('statusText') statusText;

@field('login_email_password') loginEmailPassword;

@json('roles', sanitizer) roles;
}
11 changes: 11 additions & 0 deletions app/lib/database/model/serversMigrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ export default schemaMigrations({
]
})
]
},
{
toVersion: 7,
steps: [
addColumns({
table: 'users',
columns: [
{ name: 'login_email_password', type: 'boolean', isOptional: true }
]
})
]
}
]
});
5 changes: 3 additions & 2 deletions app/lib/database/schema/servers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { appSchema, tableSchema } from '@nozbe/watermelondb';

export default appSchema({
version: 6,
version: 7,
tables: [
tableSchema({
name: 'users',
Expand All @@ -12,7 +12,8 @@ export default appSchema({
{ name: 'language', type: 'string', isOptional: true },
{ name: 'status', type: 'string', isOptional: true },
{ name: 'statusText', type: 'string', isOptional: true },
{ name: 'roles', type: 'string', isOptional: true }
{ name: 'roles', type: 'string', isOptional: true },
{ name: 'login_email_password', type: 'boolean', isOptional: true }
]
}),
tableSchema({
Expand Down
13 changes: 8 additions & 5 deletions app/lib/rocketchat.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@ const RocketChat = {
return this.post('users.forgotPassword', { email }, false);
},

loginTOTP(params) {
loginTOTP(params, loginEmailPassword) {
return new Promise(async(resolve, reject) => {
try {
const result = await this.login(params);
const result = await this.login(params, loginEmailPassword);
return resolve(result);
} catch (e) {
if (e.data?.error && (e.data.error === 'totp-required' || e.data.error === 'totp-invalid')) {
Expand Down Expand Up @@ -390,15 +390,17 @@ const RocketChat = {
};
}

return this.loginTOTP(params);
const loginEmailPassword = true;

return this.loginTOTP(params, loginEmailPassword);
},

async loginOAuthOrSso(params) {
const result = await this.login(params);
reduxStore.dispatch(loginRequest({ resume: result.token }));
},

async login(params) {
async login(params, loginEmailPassword) {
const sdk = this.shareSDK || this.sdk;
// RC 0.64.0
await sdk.login(params);
Expand All @@ -414,7 +416,8 @@ const RocketChat = {
customFields: result.me.customFields,
statusLivechat: result.me.statusLivechat,
emails: result.me.emails,
roles: result.me.roles
roles: result.me.roles,
loginEmailPassword
};
return user;
},
Expand Down
4 changes: 3 additions & 1 deletion app/sagas/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,13 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
language: user.language,
status: user.status,
statusText: user.statusText,
roles: user.roles
roles: user.roles,
loginEmailPassword: user.loginEmailPassword
};
yield serversDB.action(async() => {
try {
const userRecord = await usersCollection.find(user.id);
u.loginEmailPassword = userRecord?.loginEmailPassword;
await userRecord.update((record) => {
record._raw = sanitizedRaw({ id: user.id, ...record._raw }, usersCollection.schema);
Object.assign(record, u);
Expand Down
11 changes: 7 additions & 4 deletions app/utils/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ import I18n from '../i18n';

export const showErrorAlert = (message, title, onPress = () => {}) => Alert.alert(title, message, [{ text: 'OK', onPress }], { cancelable: true });

export const showConfirmationAlert = ({ message, callToAction, onPress }) => (
export const showConfirmationAlert = ({
title, message, confirmationText, dismissText = I18n.t('Cancel'), onPress, onCancel
}) => (
Alert.alert(
I18n.t('Are_you_sure_question_mark'),
title || I18n.t('Are_you_sure_question_mark'),
message,
[
{
text: I18n.t('Cancel'),
text: dismissText,
onPress: onCancel,
style: 'cancel'
},
{
text: callToAction,
text: confirmationText,
style: 'destructive',
onPress
}
Expand Down
2 changes: 1 addition & 1 deletion app/views/NewServerView.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class NewServerView extends React.Component {
handleRemove = () => {
showConfirmationAlert({
message: I18n.t('You_will_unset_a_certificate_for_this_server'),
callToAction: I18n.t('Remove'),
confirmationText: I18n.t('Remove'),
onPress: this.setState({ certificate: null }) // We not need delete file from DocumentPicker because it is a temp file
});
}
Expand Down
2 changes: 1 addition & 1 deletion app/views/RoomActionsView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ class RoomActionsView extends React.Component {
const { room: { rid } } = this.state;
showConfirmationAlert({
message: I18n.t('Would_you_like_to_return_the_inquiry'),
callToAction: I18n.t('Yes'),
confirmationText: I18n.t('Yes'),
onPress: async() => {
try {
await RocketChat.returnLivechat(rid);
Expand Down
2 changes: 1 addition & 1 deletion app/views/RoomMembersView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class RoomMembersView extends React.Component {
message: I18n.t(`The_user_${ userIsMuted ? 'will' : 'wont' }_be_able_to_type_in_roomName`, {
roomName: RocketChat.getRoomTitle(room)
}),
callToAction: I18n.t(userIsMuted ? 'Unmute' : 'Mute'),
confirmationText: I18n.t(userIsMuted ? 'Unmute' : 'Mute'),
onPress: () => this.handleMute(user)
});
}
Expand Down
2 changes: 1 addition & 1 deletion app/views/RoomsListView/ServerDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class ServerDropdown extends Component {

remove = server => showConfirmationAlert({
message: I18n.t('This_will_remove_all_data_from_this_server'),
callToAction: I18n.t('Delete'),
confirmationText: I18n.t('Delete'),
onPress: async() => {
this.close();
try {
Expand Down
2 changes: 1 addition & 1 deletion app/views/RoomsListView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ class RoomsListView extends React.Component {
if (user?.statusLivechat !== 'available') {
showConfirmationAlert({
message: I18n.t('Omnichannel_enable_alert'),
callToAction: I18n.t('Yes'),
confirmationText: I18n.t('Yes'),
onPress: async() => {
try {
await RocketChat.changeLivechatStatus();
Expand Down
47 changes: 40 additions & 7 deletions app/views/SettingsView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import AsyncStorage from '@react-native-community/async-storage';
import FastImage from '@rocket.chat/react-native-fast-image';
import CookieManager from '@react-native-community/cookies';

import { logout as logoutAction } from '../../actions/login';
import { selectServerRequest as selectServerRequestAction } from '../../actions/server';
Expand Down Expand Up @@ -39,7 +40,9 @@ import EventEmitter from '../../utils/events';
import { appStart as appStartAction, ROOT_LOADING } from '../../actions/app';
import { onReviewPress } from '../../utils/review';
import SafeAreaView from '../../containers/SafeAreaView';
import database from '../../lib/database';
import { isFDroidBuild } from '../../constants/environment';
import { getUserSelector } from '../../selectors/login';


const SectionSeparator = React.memo(({ theme }) => (
Expand Down Expand Up @@ -69,33 +72,62 @@ class SettingsView extends React.Component {

static propTypes = {
navigation: PropTypes.object,
server: PropTypes.object,
server: PropTypes.object,
allowCrashReport: PropTypes.bool,
toggleCrashReport: PropTypes.func,
theme: PropTypes.string,
isMasterDetail: PropTypes.bool,
logout: PropTypes.func.isRequired,
selectServerRequest: PropTypes.func,
user: PropTypes.shape({
roles: PropTypes.array,
id: PropTypes.string
}),
appStart: PropTypes.func
}

checkCookiesAndLogout = async() => {
const { logout, user } = this.props;
const db = database.servers;
const usersCollection = db.collections.get('users');
try {
const userRecord = await usersCollection.find(user.id);
if (!userRecord.loginEmailPassword) {
showConfirmationAlert({
title: I18n.t('Clear_cookies_alert'),
message: I18n.t('Clear_cookies_desc'),
confirmationText: I18n.t('Clear_cookies_yes'),
dismissText: I18n.t('Clear_cookies_no'),
onPress: async() => {
await CookieManager.clearAll(true);
logout();
},
onCancel: () => {
logout();
}
});
} else {
logout();
}
} catch {
// Do nothing: user not found
}
}

handleLogout = () => {
logEvent(events.SE_LOG_OUT);
showConfirmationAlert({
message: I18n.t('You_will_be_logged_out_of_this_application'),
callToAction: I18n.t('Logout'),
onPress: () => {
const { logout } = this.props;
logout();
}
confirmationText: I18n.t('Logout'),
onPress: this.checkCookiesAndLogout
});
}

handleClearCache = () => {
logEvent(events.SE_CLEAR_LOCAL_SERVER_CACHE);
showConfirmationAlert({
message: I18n.t('This_will_clear_all_your_offline_data'),
callToAction: I18n.t('Clear'),
confirmationText: I18n.t('Clear'),
onPress: async() => {
const {
server: { server }, appStart, selectServerRequest
Expand Down Expand Up @@ -377,6 +409,7 @@ class SettingsView extends React.Component {

const mapStateToProps = state => ({
server: state.server,
user: getUserSelector(state),
allowCrashReport: state.crashReport.allowCrashReport,
isMasterDetail: state.app.isMasterDetail
});
Expand Down
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ PODS:
- React
- react-native-cameraroll (4.0.0):
- React
- react-native-cookies (4.0.0):
- React
- react-native-document-picker (3.5.3):
- React
- react-native-jitsi-meet (2.1.1):
Expand Down Expand Up @@ -589,6 +591,7 @@ DEPENDENCIES:
- react-native-appearance (from `../node_modules/react-native-appearance`)
- react-native-background-timer (from `../node_modules/react-native-background-timer`)
- "react-native-cameraroll (from `../node_modules/@react-native-community/cameraroll`)"
- "react-native-cookies (from `../node_modules/@react-native-community/cookies`)"
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
- react-native-jitsi-meet (from `../node_modules/react-native-jitsi-meet`)
- react-native-mmkv-storage (from `../node_modules/react-native-mmkv-storage`)
Expand Down Expand Up @@ -742,6 +745,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-background-timer"
react-native-cameraroll:
:path: "../node_modules/@react-native-community/cameraroll"
react-native-cookies:
:path: "../node_modules/@react-native-community/cookies"
react-native-document-picker:
:path: "../node_modules/react-native-document-picker"
react-native-jitsi-meet:
Expand Down Expand Up @@ -911,6 +916,7 @@ SPEC CHECKSUMS:
react-native-appearance: 0f0e5fc2fcef70e03d48c8fe6b00b9158c2ba8aa
react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4
react-native-cameraroll: ae0a7c0cc8462508855707ff623b1e789b692865
react-native-cookies: d79e5015a5d3a38e08f5cb39c4948532be7e9c2b
react-native-document-picker: 825552b827012282baf4b7cbf119d3b37a280c90
react-native-jitsi-meet: f89bcb2cfbd5b15403b9c40738036c4f1af45d05
react-native-mmkv-storage: 48729fe90e850ef2fdc9d3714b7030c7c51d82b0
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions ios/Pods/Local Podspecs/react-native-cookies.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions ios/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading