incomplete fix for authentication after credential validation, #100
This commit is contained in:
@@ -12,10 +12,11 @@ export default class HashNavigation {
|
||||
path = parts[0].replace('#', '').split('/');
|
||||
}
|
||||
if (parts[1]) {
|
||||
parts[1].split('&').forEach((part) => {
|
||||
const item = part.split('=');
|
||||
if (item[0]) {
|
||||
params[decodeURIComponent(item[0])] = decodeURIComponent(item[1]);
|
||||
parts[1].split('&').forEach((arg) => {
|
||||
// Can't use split() because the value may contain '='.
|
||||
const eq = arg.indexOf('=');
|
||||
if (eq > 0) {
|
||||
params[arg.slice(0, eq)] = decodeURIComponent(arg.slice(eq + 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -31,7 +32,7 @@ export default class HashNavigation {
|
||||
const args = [];
|
||||
for (const key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
args.push(key + '=' + params[key]);
|
||||
args.push(key + '=' + encodeURIComponent(params[key]));
|
||||
}
|
||||
}
|
||||
if (args.length > 0) {
|
||||
|
||||
@@ -51,7 +51,6 @@ export default class CreateAccountView extends React.PureComponent {
|
||||
}
|
||||
|
||||
handleImageChanged(mime, img) {
|
||||
console.log("handleImageChanged", mime, img);
|
||||
this.setState({imageDataUrl: img});
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ const messages = defineMessages({
|
||||
}
|
||||
});
|
||||
|
||||
class SidepanelView extends React.Component {
|
||||
class SidepanelView extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
@@ -239,9 +239,9 @@ class SidepanelView extends React.Component {
|
||||
<ValidationView
|
||||
credCode={this.props.credCode}
|
||||
credMethod={this.props.credMethod}
|
||||
credToken={this.props.credToken}
|
||||
onSubmit={this.props.onValidateCredentials}
|
||||
onCancel={this.props.onCancel}
|
||||
onError={this.props.onError} /> :
|
||||
onCancel={this.props.onCancel} /> :
|
||||
|
||||
view === 'reset' ?
|
||||
<PasswordResetView
|
||||
|
||||
+75
-56
@@ -100,7 +100,6 @@ class TinodeWeb extends React.Component {
|
||||
this.handleConnected = this.handleConnected.bind(this);
|
||||
this.handleAutoreconnectIteration = this.handleAutoreconnectIteration.bind(this);
|
||||
this.doLogin = this.doLogin.bind(this);
|
||||
this.handleCredentialsRequest = this.handleCredentialsRequest.bind(this);
|
||||
this.handleLoginSuccessful = this.handleLoginSuccessful.bind(this);
|
||||
this.handleDisconnect = this.handleDisconnect.bind(this);
|
||||
this.tnMeMetaDesc = this.tnMeMetaDesc.bind(this);
|
||||
@@ -257,8 +256,10 @@ class TinodeWeb extends React.Component {
|
||||
searchResults: [],
|
||||
// Merged results of a search query and p2p chats.
|
||||
searchableContacts: [],
|
||||
// Credential validation.
|
||||
credMethod: undefined,
|
||||
credCode: undefined,
|
||||
credToken: undefined,
|
||||
// Topic to go to after login.
|
||||
requestedTopic: undefined
|
||||
};
|
||||
@@ -295,10 +296,10 @@ class TinodeWeb extends React.Component {
|
||||
this.tinode.onAutoreconnectIteration = this.handleAutoreconnectIteration;
|
||||
this.tinode.onInfoMessage = this.handleInfoMessage;
|
||||
this.tinode.onDataMessage = this.handleDataMessage;
|
||||
}).then(() => {
|
||||
}).then(_ => {
|
||||
// Initialize desktop alerts.
|
||||
if (this.state.desktopAlertsEnabled) {
|
||||
this.initFCMessaging().then(() => {
|
||||
this.initFCMessaging().then(_ => {
|
||||
if (this.state.desktopAlerts) {
|
||||
this.tinode.setDeviceToken(this.state.firebaseToken);
|
||||
}
|
||||
@@ -327,6 +328,9 @@ class TinodeWeb extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
this.readTimer = null;
|
||||
this.readTimerCallback = null;
|
||||
|
||||
// Maybe navigate to home screen.
|
||||
if (!['cred', 'reset', 'register'].includes(parsedNav.path[0])) {
|
||||
// Save possible topic name.
|
||||
@@ -335,12 +339,9 @@ class TinodeWeb extends React.Component {
|
||||
HashNavigation.addUrlParam('', 'cred_done', parsedNav.params.cred_done):
|
||||
'';
|
||||
HashNavigation.navigateTo(path);
|
||||
}
|
||||
|
||||
this.readTimer = null;
|
||||
this.readTimerCallback = null;
|
||||
|
||||
} else {
|
||||
this.handleHashRoute();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -471,14 +472,20 @@ class TinodeWeb extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle for hashchange event: display appropriate panels.
|
||||
// Handle for hash navigation (hashchange) event: update state.
|
||||
handleHashRoute() {
|
||||
const hash = HashNavigation.parseUrlHash(window.location.hash);
|
||||
// Start with panel parameters.
|
||||
const newState = {
|
||||
infoPanel: hash.params.info,
|
||||
newTopicTabSelected: hash.params.tab
|
||||
};
|
||||
|
||||
if (hash.path && hash.path.length > 0) {
|
||||
// Left-side panel selector.
|
||||
if (['register','settings','edit','notif','security','support','general','crop',
|
||||
'cred','reset','newtpk','archive','blocked','contacts',''].includes(hash.path[0])) {
|
||||
this.setState({sidePanelSelected: hash.path[0]});
|
||||
newState.sidePanelSelected = hash.path[0];
|
||||
} else {
|
||||
console.warn("Unknown sidepanel view", hash.path[0]);
|
||||
}
|
||||
@@ -490,33 +497,34 @@ class TinodeWeb extends React.Component {
|
||||
// Clear invalid topic name.
|
||||
topicName = null;
|
||||
}
|
||||
this.setState({
|
||||
Object.assign(newState, {
|
||||
topicSelected: topicName,
|
||||
topicSelectedAcs: this.tinode.getTopicAccessMode(topicName)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Empty hashpath
|
||||
this.setState({sidePanelSelected: '', topicSelected: null});
|
||||
Object.assign(newState, {sidePanelSelected: '', topicSelected: null});
|
||||
}
|
||||
|
||||
// Save validation credentials, if available.
|
||||
// Save credential validation parameters, if available.
|
||||
if (hash.params.method) {
|
||||
this.setState({ credMethod: hash.params.method });
|
||||
newState.credMethod = hash.params.method;
|
||||
}
|
||||
if (hash.params.code) {
|
||||
this.setState({ credCode: hash.params.code });
|
||||
newState.credCode = hash.params.code;
|
||||
}
|
||||
// Validation was successful, show a message.
|
||||
if (hash.params.cred_done) {
|
||||
this.handleError(this.props.intl.formatMessage(messages.cred_confirmed_successfully), 'info');
|
||||
if (hash.params.token) {
|
||||
newState.credToken = hash.params.token;
|
||||
}
|
||||
|
||||
// Additional parameters of panels.
|
||||
this.setState({
|
||||
infoPanel: hash.params.info,
|
||||
newTopicTabSelected: hash.params.tab
|
||||
});
|
||||
// Show a message if validation was successful.
|
||||
if (hash.params.cred_done) {
|
||||
Object.assign(newState,
|
||||
TinodeWeb.stateForError(this.props.intl.formatMessage(messages.cred_confirmed_successfully), 'info'));
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
handleOnline(online) {
|
||||
@@ -534,14 +542,18 @@ class TinodeWeb extends React.Component {
|
||||
this.setState({applicationVisible: !document.hidden});
|
||||
}
|
||||
|
||||
handleError(err, level, action, actionText) {
|
||||
this.setState({
|
||||
static stateForError(err, level, action, actionText) {
|
||||
return {
|
||||
errorText: err,
|
||||
errorLevel: level,
|
||||
errorAction: action,
|
||||
errorActionText: actionText,
|
||||
callShouldStart: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
handleError(err, level, action, actionText) {
|
||||
this.setState(TinodeWeb.stateForError(err, level, action, actionText));
|
||||
}
|
||||
|
||||
// User clicked Login button in the side panel.
|
||||
@@ -556,7 +568,7 @@ class TinodeWeb extends React.Component {
|
||||
this.handleError('', null);
|
||||
|
||||
if (this.tinode.isConnected()) {
|
||||
this.doLogin(login, password, {meth: this.state.credMethod, resp: this.state.credCode});
|
||||
this.doLogin(login, password, null, {meth: this.state.credMethod, resp: this.state.credCode});
|
||||
} else {
|
||||
this.tinode.connect().catch((err) => {
|
||||
// Socket error
|
||||
@@ -593,7 +605,8 @@ class TinodeWeb extends React.Component {
|
||||
});
|
||||
|
||||
if (this.state.autoLogin) {
|
||||
this.doLogin(this.state.login, this.state.password, {meth: this.state.credMethod, resp: this.state.credCode});
|
||||
this.doLogin(this.state.login, this.state.password, null,
|
||||
{meth: this.state.credMethod, resp: this.state.credCode});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,38 +664,48 @@ class TinodeWeb extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
doLogin(login, password, cred) {
|
||||
doLogin(login, password, tmpToken, cred) {
|
||||
if (this.tinode.isAuthenticated()) {
|
||||
// Already logged in. Go to default screen.
|
||||
HashNavigation.navigateTo('');
|
||||
return;
|
||||
}
|
||||
|
||||
let token = tmpToken || (this.tinode.getAuthToken() || {}).token;
|
||||
if (!(login && password) && !token) {
|
||||
// No login credentials provided.
|
||||
// Make sure we are on the login page.
|
||||
HashNavigation.navigateTo('');
|
||||
this.setState({loginDisabled: false});
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanitize and package credentail.
|
||||
cred = Tinode.credential(cred);
|
||||
// Try to login with login/password. If they are not available, try token. If no token, ask for login/password.
|
||||
let promise = null;
|
||||
let token = this.tinode.getAuthToken();
|
||||
// May be disconnected.
|
||||
let connectionPromise = this.tinode.isConnected() ? Promise.resolve() : this.tinode.connect();
|
||||
// Try to login with login/password. If they are not available, try token; if no token, ask for login/password.
|
||||
let loginPromise;
|
||||
if (login && password) {
|
||||
token = null;
|
||||
this.setState({password: null});
|
||||
promise = this.tinode.loginBasic(login, password, cred);
|
||||
} else if (token) {
|
||||
promise = this.tinode.loginToken(token.token, cred);
|
||||
loginPromise = connectionPromise.then(_ => this.tinode.loginBasic(login, password, cred));
|
||||
} else {
|
||||
loginPromise = connectionPromise.then(_ => this.tinode.loginToken(token, cred));
|
||||
}
|
||||
|
||||
if (promise) {
|
||||
promise.then((ctrl) => {
|
||||
loginPromise.then((ctrl) => {
|
||||
if (ctrl.code >= 300 && ctrl.text === 'validate credentials') {
|
||||
this.setState({loadSpinnerVisible: false});
|
||||
if (cred) {
|
||||
this.handleError(this.props.intl.formatMessage(messages.code_doesnot_match), 'warn');
|
||||
}
|
||||
this.handleCredentialsRequest(ctrl.params);
|
||||
TinodeWeb.navigateToCredentialsView(ctrl.params);
|
||||
} else {
|
||||
this.handleLoginSuccessful();
|
||||
}
|
||||
}).catch((err) => {
|
||||
// Login failed, report error.
|
||||
// Connection or login failed, report error.
|
||||
this.setState({
|
||||
loginDisabled: false,
|
||||
credMethod: undefined,
|
||||
@@ -691,23 +714,19 @@ class TinodeWeb extends React.Component {
|
||||
autoLogin: false
|
||||
});
|
||||
this.handleError(err.message, 'err');
|
||||
console.warn("Login failed", err);
|
||||
if (token) {
|
||||
this.handleLogout();
|
||||
}
|
||||
HashNavigation.navigateTo('');
|
||||
});
|
||||
} else {
|
||||
// No login credentials provided.
|
||||
// Make sure we are on the login page.
|
||||
HashNavigation.navigateTo('');
|
||||
this.setState({loginDisabled: false});
|
||||
}
|
||||
}
|
||||
|
||||
handleCredentialsRequest(params) {
|
||||
static navigateToCredentialsView(params) {
|
||||
const parsed = HashNavigation.parseUrlHash(window.location.hash);
|
||||
parsed.path[0] = 'cred';
|
||||
parsed.params['method'] = params.cred[0];
|
||||
parsed.params['token'] = params.token;
|
||||
HashNavigation.navigateTo(HashNavigation.composeUrlHash(parsed.path, parsed.params));
|
||||
}
|
||||
|
||||
@@ -729,6 +748,7 @@ class TinodeWeb extends React.Component {
|
||||
connected: true,
|
||||
credMethod: undefined,
|
||||
credCode: undefined,
|
||||
credToken: undefined,
|
||||
myUserId: this.tinode.getCurrentUserID(),
|
||||
autoLogin: true,
|
||||
requestedTopic: undefined,
|
||||
@@ -1110,7 +1130,7 @@ class TinodeWeb extends React.Component {
|
||||
{public: public_, tags: tags_, cred: Tinode.credential(cred_)});
|
||||
}).then((ctrl) => {
|
||||
if (ctrl.code >= 300 && ctrl.text == 'validate credentials') {
|
||||
this.handleCredentialsRequest(ctrl.params);
|
||||
TinodeWeb.navigateToCredentialsView(ctrl.params);
|
||||
} else {
|
||||
this.handleLoginSuccessful(this);
|
||||
}
|
||||
@@ -1241,7 +1261,7 @@ class TinodeWeb extends React.Component {
|
||||
}
|
||||
|
||||
handleCredConfirm(method, response) {
|
||||
this.handleCredentialsRequest({cred: [method]});
|
||||
TinodeWeb.navigateToCredentialsView({cred: [method]});
|
||||
}
|
||||
|
||||
// User clicked Cancel button in Setting or Sign Up panel.
|
||||
@@ -1661,19 +1681,17 @@ class TinodeWeb extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
handleValidateCredentialsRequest(cred, code) {
|
||||
handleValidateCredentialsRequest(cred, code, token) {
|
||||
if (this.tinode.isAuthenticated()) {
|
||||
const me = this.tinode.getMeTopic();
|
||||
me.setMeta({cred: {meth: cred, resp: code}})
|
||||
.then(_ => {
|
||||
HashNavigation.navigateTo(HashNavigation.addUrlParam('', 'cred_done', 1));
|
||||
})
|
||||
// Adding new email or phone number in account setting.
|
||||
this.tinode.getMeTopic().setMeta({cred: {meth: cred, resp: code}})
|
||||
.catch((err) => {
|
||||
this.handleError(err.message, 'err');
|
||||
});
|
||||
} else {
|
||||
this.setState({credMethod: cred, credCode: code});
|
||||
this.doLogin(null, null, {meth: cred, resp: code});
|
||||
// Credential validation on signup.
|
||||
this.setState({credMethod: cred, credCode: code, credToken: token});
|
||||
this.doLogin(null, null, token, {meth: cred, resp: code});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1955,6 +1973,7 @@ class TinodeWeb extends React.Component {
|
||||
chatList={this.state.chatList}
|
||||
credMethod={this.state.credMethod}
|
||||
credCode={this.state.credCode}
|
||||
credToken={this.state.credToken}
|
||||
|
||||
transport={this.state.transport}
|
||||
messageSounds={this.state.messageSounds}
|
||||
|
||||
@@ -41,15 +41,23 @@ class ValidationView extends React.PureComponent {
|
||||
return prevState;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
componentDidMount() {
|
||||
// Submit code automatically if it's received from the parent.
|
||||
if (this.state.codeReceived && this.state.code != prevState.code) {
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code.trim());
|
||||
if (this.props.credCode) {
|
||||
this.props.onSubmit(this.props.credMethod, this.props.credCode, this.props.credToken);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
// Submit code automatically if it's received from the parent.
|
||||
if (this.state.codeReceived && this.state.code && this.state.code != prevState.code) {
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code, this.props.credToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
handleChange(e) {
|
||||
this.setState({code: e.target.value});
|
||||
this.setState({code: e.target.value.trim()});
|
||||
}
|
||||
|
||||
handleKeyPress(e) {
|
||||
@@ -63,7 +71,7 @@ class ValidationView extends React.PureComponent {
|
||||
handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
if (this.state.code && this.state.code.trim()) {
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code.trim());
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code.trim(), this.props.credToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +83,7 @@ class ValidationView extends React.PureComponent {
|
||||
render() {
|
||||
const { formatMessage } = this.props.intl;
|
||||
const methods = {'email': formatMessage(messages.email), 'tel': formatMessage(messages.phone)};
|
||||
let method = methods[this.props.credMethod] || this.props.credMethod;
|
||||
const method = methods[this.props.credMethod] || this.props.credMethod;
|
||||
return (
|
||||
<div className="panel-form">
|
||||
<div className="panel-form-row">
|
||||
|
||||
@@ -258,7 +258,7 @@ class CallPanel extends React.PureComponent {
|
||||
}
|
||||
|
||||
handleIceCandidateErrorEvent(event) {
|
||||
console.log('ICE candidate error: ', event);
|
||||
console.warn("ICE candidate error:", event);
|
||||
}
|
||||
|
||||
handleICECandidateEvent(event) {
|
||||
@@ -301,7 +301,7 @@ class CallPanel extends React.PureComponent {
|
||||
}
|
||||
|
||||
handleICEGatheringStateChangeEvent(event) {
|
||||
// console.log('ICE gathering change state: ', event);
|
||||
// ICE gathering change state
|
||||
}
|
||||
|
||||
handleTrackEvent(event) {
|
||||
|
||||
+82
-68
@@ -3084,11 +3084,11 @@ class HashNavigation {
|
||||
}
|
||||
|
||||
if (parts[1]) {
|
||||
parts[1].split('&').forEach(part => {
|
||||
const item = part.split('=');
|
||||
parts[1].split('&').forEach(arg => {
|
||||
const eq = arg.indexOf('=');
|
||||
|
||||
if (item[0]) {
|
||||
params[decodeURIComponent(item[0])] = decodeURIComponent(item[1]);
|
||||
if (eq > 0) {
|
||||
params[arg.slice(0, eq)] = decodeURIComponent(arg.slice(eq + 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3109,7 +3109,7 @@ class HashNavigation {
|
||||
|
||||
for (const key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
args.push(key + '=' + params[key]);
|
||||
args.push(key + '=' + encodeURIComponent(params[key]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4308,7 +4308,6 @@ class CreateAccountView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
|
||||
}
|
||||
|
||||
handleImageChanged(mime, img) {
|
||||
console.log("handleImageChanged", mime, img);
|
||||
this.setState({
|
||||
imageDataUrl: img
|
||||
});
|
||||
@@ -7467,7 +7466,7 @@ const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
|
||||
}
|
||||
});
|
||||
|
||||
class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
|
||||
class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleNewTopic = this.handleNewTopic.bind(this);
|
||||
@@ -7594,9 +7593,9 @@ class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compon
|
||||
}) : view === 'cred' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_validation_view_jsx__WEBPACK_IMPORTED_MODULE_16__["default"], {
|
||||
credCode: this.props.credCode,
|
||||
credMethod: this.props.credMethod,
|
||||
credToken: this.props.credToken,
|
||||
onSubmit: this.props.onValidateCredentials,
|
||||
onCancel: this.props.onCancel,
|
||||
onError: this.props.onError
|
||||
onCancel: this.props.onCancel
|
||||
}) : view === 'reset' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_password_reset_view_jsx__WEBPACK_IMPORTED_MODULE_14__["default"], {
|
||||
onRequest: this.props.onPasswordResetRequest,
|
||||
onReset: this.props.onResetPassword,
|
||||
@@ -7756,7 +7755,6 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
this.handleConnected = this.handleConnected.bind(this);
|
||||
this.handleAutoreconnectIteration = this.handleAutoreconnectIteration.bind(this);
|
||||
this.doLogin = this.doLogin.bind(this);
|
||||
this.handleCredentialsRequest = this.handleCredentialsRequest.bind(this);
|
||||
this.handleLoginSuccessful = this.handleLoginSuccessful.bind(this);
|
||||
this.handleDisconnect = this.handleDisconnect.bind(this);
|
||||
this.tnMeMetaDesc = this.tnMeMetaDesc.bind(this);
|
||||
@@ -7883,6 +7881,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
searchableContacts: [],
|
||||
credMethod: undefined,
|
||||
credCode: undefined,
|
||||
credToken: undefined,
|
||||
requestedTopic: undefined
|
||||
};
|
||||
}
|
||||
@@ -7916,9 +7915,9 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
this.tinode.onAutoreconnectIteration = this.handleAutoreconnectIteration;
|
||||
this.tinode.onInfoMessage = this.handleInfoMessage;
|
||||
this.tinode.onDataMessage = this.handleDataMessage;
|
||||
}).then(() => {
|
||||
}).then(_ => {
|
||||
if (this.state.desktopAlertsEnabled) {
|
||||
this.initFCMessaging().then(() => {
|
||||
this.initFCMessaging().then(_ => {
|
||||
if (this.state.desktopAlerts) {
|
||||
this.tinode.setDeviceToken(this.state.firebaseToken);
|
||||
}
|
||||
@@ -7940,17 +7939,18 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}
|
||||
|
||||
this.readTimer = null;
|
||||
this.readTimerCallback = null;
|
||||
|
||||
if (!['cred', 'reset', 'register'].includes(parsedNav.path[0])) {
|
||||
this.setState({
|
||||
requestedTopic: parsedNav.path[1]
|
||||
});
|
||||
const path = parsedNav.params && parsedNav.params.cred_done ? _lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].addUrlParam('', 'cred_done', parsedNav.params.cred_done) : '';
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo(path);
|
||||
}
|
||||
|
||||
this.readTimer = null;
|
||||
this.readTimerCallback = null;
|
||||
} else {
|
||||
this.handleHashRoute();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8113,12 +8113,14 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
|
||||
handleHashRoute() {
|
||||
const hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].parseUrlHash(window.location.hash);
|
||||
const newState = {
|
||||
infoPanel: hash.params.info,
|
||||
newTopicTabSelected: hash.params.tab
|
||||
};
|
||||
|
||||
if (hash.path && hash.path.length > 0) {
|
||||
if (['register', 'settings', 'edit', 'notif', 'security', 'support', 'general', 'crop', 'cred', 'reset', 'newtpk', 'archive', 'blocked', 'contacts', ''].includes(hash.path[0])) {
|
||||
this.setState({
|
||||
sidePanelSelected: hash.path[0]
|
||||
});
|
||||
newState.sidePanelSelected = hash.path[0];
|
||||
} else {
|
||||
console.warn("Unknown sidepanel view", hash.path[0]);
|
||||
}
|
||||
@@ -8130,38 +8132,35 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
topicName = null;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
Object.assign(newState, {
|
||||
topicSelected: topicName,
|
||||
topicSelectedAcs: this.tinode.getTopicAccessMode(topicName)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
Object.assign(newState, {
|
||||
sidePanelSelected: '',
|
||||
topicSelected: null
|
||||
});
|
||||
}
|
||||
|
||||
if (hash.params.method) {
|
||||
this.setState({
|
||||
credMethod: hash.params.method
|
||||
});
|
||||
newState.credMethod = hash.params.method;
|
||||
}
|
||||
|
||||
if (hash.params.code) {
|
||||
this.setState({
|
||||
credCode: hash.params.code
|
||||
});
|
||||
newState.credCode = hash.params.code;
|
||||
}
|
||||
|
||||
if (hash.params.token) {
|
||||
newState.credToken = hash.params.token;
|
||||
}
|
||||
|
||||
if (hash.params.cred_done) {
|
||||
this.handleError(this.props.intl.formatMessage(messages.cred_confirmed_successfully), 'info');
|
||||
Object.assign(newState, TinodeWeb.stateForError(this.props.intl.formatMessage(messages.cred_confirmed_successfully), 'info'));
|
||||
}
|
||||
|
||||
this.setState({
|
||||
infoPanel: hash.params.info,
|
||||
newTopicTabSelected: hash.params.tab
|
||||
});
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
handleOnline(online) {
|
||||
@@ -8184,14 +8183,18 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}
|
||||
|
||||
handleError(err, level, action, actionText) {
|
||||
this.setState({
|
||||
static stateForError(err, level, action, actionText) {
|
||||
return {
|
||||
errorText: err,
|
||||
errorLevel: level,
|
||||
errorAction: action,
|
||||
errorActionText: actionText,
|
||||
callShouldStart: false
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
handleError(err, level, action, actionText) {
|
||||
this.setState(TinodeWeb.stateForError(err, level, action, actionText));
|
||||
}
|
||||
|
||||
handleLoginRequest(login, password) {
|
||||
@@ -8205,7 +8208,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
this.handleError('', null);
|
||||
|
||||
if (this.tinode.isConnected()) {
|
||||
this.doLogin(login, password, {
|
||||
this.doLogin(login, password, null, {
|
||||
meth: this.state.credMethod,
|
||||
resp: this.state.credCode
|
||||
});
|
||||
@@ -8248,7 +8251,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
|
||||
if (this.state.autoLogin) {
|
||||
this.doLogin(this.state.login, this.state.password, {
|
||||
this.doLogin(this.state.login, this.state.password, null, {
|
||||
meth: this.state.credMethod,
|
||||
resp: this.state.credCode
|
||||
});
|
||||
@@ -8303,28 +8306,37 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}
|
||||
|
||||
doLogin(login, password, cred) {
|
||||
doLogin(login, password, tmpToken, cred) {
|
||||
if (this.tinode.isAuthenticated()) {
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo('');
|
||||
return;
|
||||
}
|
||||
|
||||
let token = tmpToken || (this.tinode.getAuthToken() || {}).token;
|
||||
|
||||
if (!(login && password) && !token) {
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo('');
|
||||
this.setState({
|
||||
loginDisabled: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
cred = tinode_sdk__WEBPACK_IMPORTED_MODULE_4__.Tinode.credential(cred);
|
||||
let promise = null;
|
||||
let token = this.tinode.getAuthToken();
|
||||
let connectionPromise = this.tinode.isConnected() ? Promise.resolve() : this.tinode.connect();
|
||||
let loginPromise;
|
||||
|
||||
if (login && password) {
|
||||
token = null;
|
||||
this.setState({
|
||||
password: null
|
||||
});
|
||||
promise = this.tinode.loginBasic(login, password, cred);
|
||||
} else if (token) {
|
||||
promise = this.tinode.loginToken(token.token, cred);
|
||||
loginPromise = connectionPromise.then(_ => this.tinode.loginBasic(login, password, cred));
|
||||
} else {
|
||||
loginPromise = connectionPromise.then(_ => this.tinode.loginToken(token, cred));
|
||||
}
|
||||
|
||||
if (promise) {
|
||||
promise.then(ctrl => {
|
||||
loginPromise.then(ctrl => {
|
||||
if (ctrl.code >= 300 && ctrl.text === 'validate credentials') {
|
||||
this.setState({
|
||||
loadSpinnerVisible: false
|
||||
@@ -8334,7 +8346,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
this.handleError(this.props.intl.formatMessage(messages.code_doesnot_match), 'warn');
|
||||
}
|
||||
|
||||
this.handleCredentialsRequest(ctrl.params);
|
||||
TinodeWeb.navigateToCredentialsView(ctrl.params);
|
||||
} else {
|
||||
this.handleLoginSuccessful();
|
||||
}
|
||||
@@ -8347,6 +8359,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
autoLogin: false
|
||||
});
|
||||
this.handleError(err.message, 'err');
|
||||
console.warn("Login failed", err);
|
||||
|
||||
if (token) {
|
||||
this.handleLogout();
|
||||
@@ -8354,18 +8367,13 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo('');
|
||||
});
|
||||
} else {
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo('');
|
||||
this.setState({
|
||||
loginDisabled: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleCredentialsRequest(params) {
|
||||
static navigateToCredentialsView(params) {
|
||||
const parsed = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].parseUrlHash(window.location.hash);
|
||||
parsed.path[0] = 'cred';
|
||||
parsed.params['method'] = params.cred[0];
|
||||
parsed.params['token'] = params.token;
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].composeUrlHash(parsed.path, parsed.params));
|
||||
}
|
||||
|
||||
@@ -8385,6 +8393,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
connected: true,
|
||||
credMethod: undefined,
|
||||
credCode: undefined,
|
||||
credToken: undefined,
|
||||
myUserId: this.tinode.getCurrentUserID(),
|
||||
autoLogin: true,
|
||||
requestedTopic: undefined
|
||||
@@ -8738,7 +8747,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}).then(ctrl => {
|
||||
if (ctrl.code >= 300 && ctrl.text == 'validate credentials') {
|
||||
this.handleCredentialsRequest(ctrl.params);
|
||||
TinodeWeb.navigateToCredentialsView(ctrl.params);
|
||||
} else {
|
||||
this.handleLoginSuccessful(this);
|
||||
}
|
||||
@@ -8889,7 +8898,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
}
|
||||
|
||||
handleCredConfirm(method, response) {
|
||||
this.handleCredentialsRequest({
|
||||
TinodeWeb.navigateToCredentialsView({
|
||||
cred: [method]
|
||||
});
|
||||
}
|
||||
@@ -9347,25 +9356,23 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
}
|
||||
}
|
||||
|
||||
handleValidateCredentialsRequest(cred, code) {
|
||||
handleValidateCredentialsRequest(cred, code, token) {
|
||||
if (this.tinode.isAuthenticated()) {
|
||||
const me = this.tinode.getMeTopic();
|
||||
me.setMeta({
|
||||
this.tinode.getMeTopic().setMeta({
|
||||
cred: {
|
||||
meth: cred,
|
||||
resp: code
|
||||
}
|
||||
}).then(_ => {
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].addUrlParam('', 'cred_done', 1));
|
||||
}).catch(err => {
|
||||
this.handleError(err.message, 'err');
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
credMethod: cred,
|
||||
credCode: code
|
||||
credCode: code,
|
||||
credToken: token
|
||||
});
|
||||
this.doLogin(null, null, {
|
||||
this.doLogin(null, null, token, {
|
||||
meth: cred,
|
||||
resp: code
|
||||
});
|
||||
@@ -9648,6 +9655,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
chatList: this.state.chatList,
|
||||
credMethod: this.state.credMethod,
|
||||
credCode: this.state.credCode,
|
||||
credToken: this.state.credToken,
|
||||
transport: this.state.transport,
|
||||
messageSounds: this.state.messageSounds,
|
||||
desktopAlerts: this.state.desktopAlerts,
|
||||
@@ -9823,15 +9831,21 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
|
||||
return prevState;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.credCode) {
|
||||
this.props.onSubmit(this.props.credMethod, this.props.credCode, this.props.credToken);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (this.state.codeReceived && this.state.code != prevState.code) {
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code.trim());
|
||||
if (this.state.codeReceived && this.state.code && this.state.code != prevState.code) {
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code, this.props.credToken);
|
||||
}
|
||||
}
|
||||
|
||||
handleChange(e) {
|
||||
this.setState({
|
||||
code: e.target.value
|
||||
code: e.target.value.trim()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9847,7 +9861,7 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.code && this.state.code.trim()) {
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code.trim());
|
||||
this.props.onSubmit(this.props.credMethod, this.state.code.trim(), this.props.credToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9864,7 +9878,7 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
|
||||
'email': formatMessage(messages.email),
|
||||
'tel': formatMessage(messages.phone)
|
||||
};
|
||||
let method = methods[this.props.credMethod] || this.props.credMethod;
|
||||
const method = methods[this.props.credMethod] || this.props.credMethod;
|
||||
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "panel-form"
|
||||
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
@@ -11595,7 +11609,7 @@ class CallPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
|
||||
}
|
||||
|
||||
handleIceCandidateErrorEvent(event) {
|
||||
console.log('ICE candidate error: ', event);
|
||||
console.warn("ICE candidate error:", event);
|
||||
}
|
||||
|
||||
handleICECandidateEvent(event) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user