diff --git a/.gitignore b/.gitignore index b99c9f1145..f828c37393 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ npm-debug.log /.idea /src/component-index.js + +.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 870b42ecfc..66e4627afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.9.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.2) (2017-06-06) +=================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.1...v0.9.2) + + * Hotfix: Allow password reset when logged in + [\#1044](https://github.com/matrix-org/matrix-react-sdk/pull/1044) + Changes in [0.9.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.9.1) (2017-06-02) =================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.9.0...v0.9.1) diff --git a/package.json b/package.json index 97e9426243..15a903c25a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.9.1", + "version": "0.9.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { @@ -66,6 +66,7 @@ "lodash": "^4.13.1", "matrix-js-sdk": "0.7.10", "optimist": "^0.6.1", + "prop-types": "^15.5.8", "q": "^1.4.1", "react": "^15.4.0", "react-addons-css-transition-group": "15.3.2", diff --git a/src/CallMediaHandler.js b/src/CallMediaHandler.js index 45ca5dc30d..839b496845 100644 --- a/src/CallMediaHandler.js +++ b/src/CallMediaHandler.js @@ -16,7 +16,6 @@ import UserSettingsStore from './UserSettingsStore'; import * as Matrix from 'matrix-js-sdk'; -import q from 'q'; export default { getDevices: function() { diff --git a/src/KeyCode.js b/src/KeyCode.js index c9cac01239..28aafc00cb 100644 --- a/src/KeyCode.js +++ b/src/KeyCode.js @@ -32,4 +32,5 @@ module.exports = { DELETE: 46, KEY_D: 68, KEY_E: 69, + KEY_M: 77, }; diff --git a/src/Lifecycle.js b/src/Lifecycle.js index a3bec14492..54014a0166 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -187,6 +187,14 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { // returns a promise which resolves to true if a session is found in // localstorage +// +// N.B. Lifecycle.js should not maintain any further localStorage state, we +// are moving towards using SessionStore to keep track of state related +// to the current session (which is typically backed by localStorage). +// +// The plan is to gradually move the localStorage access done here into +// SessionStore to avoid bugs where the view becomes out-of-sync with +// localStorage (e.g. teamToken, isGuest etc.) function _restoreFromLocalStorage() { if (!localStorage) { return q(false); @@ -237,7 +245,7 @@ function _handleRestoreFailure(e) { + ' This is a once off; sorry for the inconvenience.', ); - _clearStorage(); + _clearLocalStorage(); return q.reject(new Error( _t('Unable to restore previous session') + ': ' + msg, @@ -258,7 +266,7 @@ function _handleRestoreFailure(e) { return def.promise.then((success) => { if (success) { // user clicked continue. - _clearStorage(); + _clearLocalStorage(); return false; } @@ -314,6 +322,16 @@ export function setLoggedIn(credentials) { localStorage.setItem("mx_device_id", credentials.deviceId); } + // The user registered as a PWLU (PassWord-Less User), the generated password + // is cached here such that the user can change it at a later time. + if (credentials.password) { + // Update SessionStore + dis.dispatch({ + action: 'cached_password', + cachedPassword: credentials.password, + }); + } + console.log("Session persisted for %s", credentials.userId); } catch (e) { console.warn("Error using local storage: can't persist session!", e); @@ -332,10 +350,6 @@ export function setLoggedIn(credentials) { } // stop any running clients before we create a new one with these new credentials - // - // XXX: why do we have any running clients here? Maybe on sign-in after - // initial use as a guest? but what about our persistent storage? we need to - // be careful not to leak e2e data created as one user into another session. stopMatrixClient(); MatrixClientPeg.replaceUsingCreds(credentials); @@ -406,19 +420,13 @@ export function startMatrixClient() { * a session has been logged out / ended. */ export function onLoggedOut() { - stopMatrixClient(true); + _clearLocalStorage(); + stopMatrixClient(); dis.dispatch({action: 'on_logged_out'}); } -function _clearStorage() { +function _clearLocalStorage() { Analytics.logout(); - - const cli = MatrixClientPeg.get(); - if (cli) { - // TODO: *really* ought to wait for the promise to complete - cli.clearStores().done(); - } - if (!window.localStorage) { return; } @@ -435,13 +443,9 @@ function _clearStorage() { } /** - * Stop all the background processes related to the current client. - * - * Optionally clears persistent stores. - * - * @param {boolean} clearStores true to clear the persistent stores. + * Stop all the background processes related to the current client */ -export function stopMatrixClient(clearStores) { +export function stopMatrixClient() { Notifier.stop(); UserActivity.stop(); Presence.stop(); @@ -450,13 +454,7 @@ export function stopMatrixClient(clearStores) { if (cli) { cli.stopClient(); cli.removeAllListeners(); + cli.store.deleteAllData(); + MatrixClientPeg.unset(); } - - if (clearStores) { - // note that we have to do this *after* stopping the client, but - // *before* clearing the MatrixClientPeg. - _clearStorage(); - } - - MatrixClientPeg.unset(); } diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 452b67c4ee..94e55a8d8a 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -16,7 +16,6 @@ limitations under the License. 'use strict'; -import q from "q"; import Matrix from 'matrix-js-sdk'; import utils from 'matrix-js-sdk/lib/utils'; import EventTimeline from 'matrix-js-sdk/lib/models/event-timeline'; diff --git a/src/Rooms.js b/src/Rooms.js index 08fa7f797f..16b5ab9ee2 100644 --- a/src/Rooms.js +++ b/src/Rooms.js @@ -15,7 +15,6 @@ limitations under the License. */ import MatrixClientPeg from './MatrixClientPeg'; -import DMRoomMap from './utils/DMRoomMap'; import q from 'q'; /** diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js index 8c591f7cb2..c1b975e8e8 100644 --- a/src/ScalarMessaging.js +++ b/src/ScalarMessaging.js @@ -94,6 +94,22 @@ Example: } } +get_membership_count +-------------------- +Get the number of joined users in the room. + +Request: + - room_id is the room to get the count in. +Response: +78 +Example: +{ + action: "get_membership_count", + room_id: "!foo:bar", + response: 78 +} + + membership_state AND bot_options -------------------------------- Get the content of the "m.room.member" or "m.room.bot.options" state event respectively. @@ -256,6 +272,21 @@ function botOptions(event, roomId, userId) { returnStateEvent(event, roomId, "m.room.bot.options", "_" + userId); } +function getMembershipCount(event, roomId) { + const client = MatrixClientPeg.get(); + if (!client) { + sendError(event, _t('You need to be logged in.')); + return; + } + const room = client.getRoom(roomId); + if (!room) { + sendError(event, _t('This room is not recognised.')); + return; + } + const count = room.getJoinedMembers().length; + sendResponse(event, count); +} + function returnStateEvent(event, roomId, eventType, stateKey) { const client = MatrixClientPeg.get(); if (!client) { @@ -343,6 +374,9 @@ const onMessage = function(event) { } else if (event.data.action === "set_plumbing_state") { setPlumbingState(event, roomId, event.data.status); return; + } else if (event.data.action === "get_membership_count") { + getMembershipCount(event, roomId); + return; } if (!userId) { diff --git a/src/autocomplete/Components.js b/src/autocomplete/Components.js index b26a217ec6..0f0399cf7d 100644 --- a/src/autocomplete/Components.js +++ b/src/autocomplete/Components.js @@ -15,7 +15,6 @@ limitations under the License. */ import React from 'react'; -import ReactDOM from 'react-dom'; import classNames from 'classnames'; /* These were earlier stateless functional components but had to be converted diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index fedebb3618..809fec94be 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -18,7 +18,6 @@ limitations under the License. import React from 'react'; import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; -import Q from 'q'; import Fuse from 'fuse.js'; import {PillCompletion} from './Components'; import sdk from '../index'; diff --git a/src/components/structures/CreateRoom.js b/src/components/structures/CreateRoom.js index 8b3d035dc1..3e291dfd94 100644 --- a/src/components/structures/CreateRoom.js +++ b/src/components/structures/CreateRoom.js @@ -17,7 +17,6 @@ limitations under the License. 'use strict'; import React from 'react'; -import q from 'q'; import { _t } from '../../languageHandler'; import sdk from '../../index'; import MatrixClientPeg from '../../MatrixClientPeg'; @@ -247,7 +246,7 @@ module.exports = React.createClass({ return (
- +