Merge pull request #82 from matrix-org/kegan/guest-access
Implement guest access and upgrading
This commit is contained in:
commit
3cd805e71d
11 changed files with 269 additions and 45 deletions
51
src/GuestAccess.js
Normal file
51
src/GuestAccess.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015 OpenMarket Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
const IS_GUEST_KEY = "matrix-is-guest";
|
||||||
|
|
||||||
|
class GuestAccess {
|
||||||
|
|
||||||
|
constructor(localStorage) {
|
||||||
|
this.localStorage = localStorage;
|
||||||
|
try {
|
||||||
|
this._isGuest = localStorage.getItem(IS_GUEST_KEY) === "true";
|
||||||
|
}
|
||||||
|
catch (e) {} // don't care
|
||||||
|
}
|
||||||
|
|
||||||
|
setPeekedRoom(roomId) {
|
||||||
|
// we purposefully do not persist this to local storage as peeking is
|
||||||
|
// entirely transient.
|
||||||
|
this._peekedRoomId = roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPeekedRoom() {
|
||||||
|
return this._peekedRoomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
isGuest() {
|
||||||
|
return this._isGuest;
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsGuest(isGuest) {
|
||||||
|
try {
|
||||||
|
this.localStorage.setItem(IS_GUEST_KEY, JSON.stringify(isGuest));
|
||||||
|
} catch (e) {} // ignore. If they don't do LS, they'll just get a new account.
|
||||||
|
this._isGuest = isGuest;
|
||||||
|
this._peekedRoomId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = GuestAccess;
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||||
|
|
||||||
// A thing that holds your Matrix Client
|
// A thing that holds your Matrix Client
|
||||||
var Matrix = require("matrix-js-sdk");
|
var Matrix = require("matrix-js-sdk");
|
||||||
|
var GuestAccess = require("./GuestAccess");
|
||||||
|
|
||||||
var matrixClient = null;
|
var matrixClient = null;
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ function deviceId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createClient(hs_url, is_url, user_id, access_token) {
|
function createClient(hs_url, is_url, user_id, access_token, guestAccess) {
|
||||||
var opts = {
|
var opts = {
|
||||||
baseUrl: hs_url,
|
baseUrl: hs_url,
|
||||||
idBaseUrl: is_url,
|
idBaseUrl: is_url,
|
||||||
|
@ -47,6 +48,15 @@ function createClient(hs_url, is_url, user_id, access_token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
matrixClient = Matrix.createClient(opts);
|
matrixClient = Matrix.createClient(opts);
|
||||||
|
if (guestAccess) {
|
||||||
|
console.log("Guest: %s", guestAccess.isGuest());
|
||||||
|
matrixClient.setGuest(guestAccess.isGuest());
|
||||||
|
var peekedRoomId = guestAccess.getPeekedRoom();
|
||||||
|
if (peekedRoomId) {
|
||||||
|
console.log("Peeking in room %s", peekedRoomId);
|
||||||
|
matrixClient.peekInRoom(peekedRoomId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
|
@ -54,12 +64,18 @@ if (localStorage) {
|
||||||
var is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
var is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
||||||
var access_token = localStorage.getItem("mx_access_token");
|
var access_token = localStorage.getItem("mx_access_token");
|
||||||
var user_id = localStorage.getItem("mx_user_id");
|
var user_id = localStorage.getItem("mx_user_id");
|
||||||
|
var guestAccess = new GuestAccess(localStorage);
|
||||||
if (access_token && user_id && hs_url) {
|
if (access_token && user_id && hs_url) {
|
||||||
createClient(hs_url, is_url, user_id, access_token);
|
createClient(hs_url, is_url, user_id, access_token, guestAccess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MatrixClient {
|
class MatrixClient {
|
||||||
|
|
||||||
|
constructor(guestAccess) {
|
||||||
|
this.guestAccess = guestAccess;
|
||||||
|
}
|
||||||
|
|
||||||
get() {
|
get() {
|
||||||
return matrixClient;
|
return matrixClient;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +113,7 @@ class MatrixClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceUsingAccessToken(hs_url, is_url, user_id, access_token) {
|
replaceUsingAccessToken(hs_url, is_url, user_id, access_token, isGuest) {
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
try {
|
try {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
@ -105,7 +121,8 @@ class MatrixClient {
|
||||||
console.warn("Error using local storage");
|
console.warn("Error using local storage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createClient(hs_url, is_url, user_id, access_token);
|
this.guestAccess.markAsGuest(Boolean(isGuest));
|
||||||
|
createClient(hs_url, is_url, user_id, access_token, this.guestAccess);
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
try {
|
try {
|
||||||
localStorage.setItem("mx_hs_url", hs_url);
|
localStorage.setItem("mx_hs_url", hs_url);
|
||||||
|
@ -122,6 +139,6 @@ class MatrixClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!global.mxMatrixClient) {
|
if (!global.mxMatrixClient) {
|
||||||
global.mxMatrixClient = new MatrixClient();
|
global.mxMatrixClient = new MatrixClient(new GuestAccess(localStorage));
|
||||||
}
|
}
|
||||||
module.exports = global.mxMatrixClient;
|
module.exports = global.mxMatrixClient;
|
||||||
|
|
|
@ -73,6 +73,11 @@ class Presence {
|
||||||
}
|
}
|
||||||
var old_state = this.state;
|
var old_state = this.state;
|
||||||
this.state = newState;
|
this.state = newState;
|
||||||
|
|
||||||
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
|
return; // don't try to set presence when a guest; it won't work.
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
MatrixClientPeg.get().setPresence(this.state).done(function() {
|
MatrixClientPeg.get().setPresence(this.state).done(function() {
|
||||||
console.log("Presence: %s", newState);
|
console.log("Presence: %s", newState);
|
||||||
|
|
|
@ -69,6 +69,10 @@ class Register extends Signup {
|
||||||
this.params.idSid = idSid;
|
this.params.idSid = idSid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGuestAccessToken(token) {
|
||||||
|
this.guestAccessToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
getStep() {
|
getStep() {
|
||||||
return this._step;
|
return this._step;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +130,8 @@ class Register extends Signup {
|
||||||
}
|
}
|
||||||
|
|
||||||
return MatrixClientPeg.get().register(
|
return MatrixClientPeg.get().register(
|
||||||
this.username, this.password, this.params.sessionId, authDict, bindEmail
|
this.username, this.password, this.params.sessionId, authDict, bindEmail,
|
||||||
|
this.guestAccessToken
|
||||||
).then(function(result) {
|
).then(function(result) {
|
||||||
self.credentials = result;
|
self.credentials = result;
|
||||||
self.setStep("COMPLETE");
|
self.setStep("COMPLETE");
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
var q = require("q");
|
||||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
var MatrixClientPeg = require("./MatrixClientPeg");
|
||||||
var Notifier = require("./Notifier");
|
var Notifier = require("./Notifier");
|
||||||
|
|
||||||
|
@ -35,6 +35,11 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
loadThreePids: function() {
|
loadThreePids: function() {
|
||||||
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
|
return q({
|
||||||
|
threepids: []
|
||||||
|
}); // guests can't poke 3pid endpoint
|
||||||
|
}
|
||||||
return MatrixClientPeg.get().getThreePids();
|
return MatrixClientPeg.get().getThreePids();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ module.exports = React.createClass({
|
||||||
ConferenceHandler: React.PropTypes.any,
|
ConferenceHandler: React.PropTypes.any,
|
||||||
onNewScreen: React.PropTypes.func,
|
onNewScreen: React.PropTypes.func,
|
||||||
registrationUrl: React.PropTypes.string,
|
registrationUrl: React.PropTypes.string,
|
||||||
|
enableGuest: React.PropTypes.bool,
|
||||||
startingQueryParams: React.PropTypes.object
|
startingQueryParams: React.PropTypes.object
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -83,8 +84,21 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
this._autoRegisterAsGuest = false;
|
||||||
|
if (this.props.enableGuest) {
|
||||||
|
if (!this.props.config || !this.props.config.default_hs_url) {
|
||||||
|
console.error("Cannot enable guest access: No supplied config prop for HS/IS URLs");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._autoRegisterAsGuest = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
if (this.state.logged_in) {
|
if (this.state.logged_in) {
|
||||||
|
// Don't auto-register as a guest. This applies if you refresh the page on a
|
||||||
|
// logged in client THEN hit the Sign Out button.
|
||||||
|
this._autoRegisterAsGuest = false;
|
||||||
this.startMatrixClient();
|
this.startMatrixClient();
|
||||||
}
|
}
|
||||||
this.focusComposer = false;
|
this.focusComposer = false;
|
||||||
|
@ -93,8 +107,11 @@ module.exports = React.createClass({
|
||||||
this.scrollStateMap = {};
|
this.scrollStateMap = {};
|
||||||
document.addEventListener("keydown", this.onKeyDown);
|
document.addEventListener("keydown", this.onKeyDown);
|
||||||
window.addEventListener("focus", this.onFocus);
|
window.addEventListener("focus", this.onFocus);
|
||||||
|
|
||||||
if (this.state.logged_in) {
|
if (this.state.logged_in) {
|
||||||
this.notifyNewScreen('');
|
this.notifyNewScreen('');
|
||||||
|
} else if (this._autoRegisterAsGuest) {
|
||||||
|
this._registerAsGuest();
|
||||||
} else {
|
} else {
|
||||||
this.notifyNewScreen('login');
|
this.notifyNewScreen('login');
|
||||||
}
|
}
|
||||||
|
@ -126,6 +143,34 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_registerAsGuest: function() {
|
||||||
|
var self = this;
|
||||||
|
var config = this.props.config;
|
||||||
|
console.log("Doing guest login on %s", config.default_hs_url);
|
||||||
|
MatrixClientPeg.replaceUsingUrls(
|
||||||
|
config.default_hs_url, config.default_is_url
|
||||||
|
);
|
||||||
|
MatrixClientPeg.get().registerGuest().done(function(creds) {
|
||||||
|
console.log("Registered as guest: %s", creds.user_id);
|
||||||
|
self._setAutoRegisterAsGuest(false);
|
||||||
|
self.onLoggedIn({
|
||||||
|
userId: creds.user_id,
|
||||||
|
accessToken: creds.access_token,
|
||||||
|
homeserverUrl: config.default_hs_url,
|
||||||
|
identityServerUrl: config.default_is_url,
|
||||||
|
guest: true
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
console.error(err.data);
|
||||||
|
self._setAutoRegisterAsGuest(false);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_setAutoRegisterAsGuest: function(shouldAutoRegister) {
|
||||||
|
this._autoRegisterAsGuest = shouldAutoRegister;
|
||||||
|
this.forceUpdate();
|
||||||
|
},
|
||||||
|
|
||||||
onAction: function(payload) {
|
onAction: function(payload) {
|
||||||
var roomIndexDelta = 1;
|
var roomIndexDelta = 1;
|
||||||
|
|
||||||
|
@ -180,6 +225,14 @@ module.exports = React.createClass({
|
||||||
screen: 'post_registration'
|
screen: 'post_registration'
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'start_upgrade_registration':
|
||||||
|
this.replaceState({
|
||||||
|
screen: "register",
|
||||||
|
upgradeUsername: MatrixClientPeg.get().getUserIdLocalpart(),
|
||||||
|
guestAccessToken: MatrixClientPeg.get().getAccessToken()
|
||||||
|
});
|
||||||
|
this.notifyNewScreen('register');
|
||||||
|
break;
|
||||||
case 'token_login':
|
case 'token_login':
|
||||||
if (this.state.logged_in) return;
|
if (this.state.logged_in) return;
|
||||||
|
|
||||||
|
@ -382,10 +435,11 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoggedIn: function(credentials) {
|
onLoggedIn: function(credentials) {
|
||||||
console.log("onLoggedIn => %s", credentials.userId);
|
credentials.guest = Boolean(credentials.guest);
|
||||||
|
console.log("onLoggedIn => %s (guest=%s)", credentials.userId, credentials.guest);
|
||||||
MatrixClientPeg.replaceUsingAccessToken(
|
MatrixClientPeg.replaceUsingAccessToken(
|
||||||
credentials.homeserverUrl, credentials.identityServerUrl,
|
credentials.homeserverUrl, credentials.identityServerUrl,
|
||||||
credentials.userId, credentials.accessToken
|
credentials.userId, credentials.accessToken, credentials.guest
|
||||||
);
|
);
|
||||||
this.setState({
|
this.setState({
|
||||||
screen: undefined,
|
screen: undefined,
|
||||||
|
@ -715,12 +769,20 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (this.state.logged_in) {
|
} else if (this.state.logged_in || (!this.state.logged_in && this._autoRegisterAsGuest)) {
|
||||||
var Spinner = sdk.getComponent('elements.Spinner');
|
var Spinner = sdk.getComponent('elements.Spinner');
|
||||||
|
var logoutLink;
|
||||||
|
if (this.state.logged_in) {
|
||||||
|
logoutLink = (
|
||||||
|
<a href="#" className="mx_MatrixChat_splashButtons" onClick={ this.onLogoutClick }>
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="mx_MatrixChat_splash">
|
<div className="mx_MatrixChat_splash">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
<a href="#" className="mx_MatrixChat_splashButtons" onClick={ this.onLogoutClick }>Logout</a>
|
{logoutLink}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (this.state.screen == 'register') {
|
} else if (this.state.screen == 'register') {
|
||||||
|
@ -730,6 +792,9 @@ module.exports = React.createClass({
|
||||||
sessionId={this.state.register_session_id}
|
sessionId={this.state.register_session_id}
|
||||||
idSid={this.state.register_id_sid}
|
idSid={this.state.register_id_sid}
|
||||||
email={this.props.startingQueryParams.email}
|
email={this.props.startingQueryParams.email}
|
||||||
|
username={this.state.upgradeUsername}
|
||||||
|
disableUsernameChanges={Boolean(this.state.upgradeUsername)}
|
||||||
|
guestAccessToken={this.state.guestAccessToken}
|
||||||
hsUrl={this.props.config.default_hs_url}
|
hsUrl={this.props.config.default_hs_url}
|
||||||
isUrl={this.props.config.default_is_url}
|
isUrl={this.props.config.default_is_url}
|
||||||
registrationUrl={this.props.registrationUrl}
|
registrationUrl={this.props.registrationUrl}
|
||||||
|
|
|
@ -97,6 +97,24 @@ module.exports = React.createClass({
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// if this is an unknown room then we're in one of three states:
|
||||||
|
// - This is a room we can peek into (search engine) (we can /peek)
|
||||||
|
// - This is a room we can publicly join or were invited to. (we can /join)
|
||||||
|
// - This is a room we cannot join at all. (no action can help us)
|
||||||
|
// We can't try to /join because this may implicitly accept invites (!)
|
||||||
|
// We can /peek though. If it fails then we present the join UI. If it
|
||||||
|
// succeeds then great, show the preview (but we still may be able to /join!).
|
||||||
|
if (!this.state.room) {
|
||||||
|
console.log("Attempting to peek into room %s", this.props.roomId);
|
||||||
|
MatrixClientPeg.get().peekInRoom(this.props.roomId).done(function() {
|
||||||
|
// we don't need to do anything - JS SDK will emit Room events
|
||||||
|
// which will update the UI.
|
||||||
|
}, function(err) {
|
||||||
|
console.error("Failed to peek into room: %s", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
|
@ -422,6 +440,12 @@ module.exports = React.createClass({
|
||||||
joining: false,
|
joining: false,
|
||||||
joinError: error
|
joinError: error
|
||||||
});
|
});
|
||||||
|
var msg = error.message ? error.message : JSON.stringify(error);
|
||||||
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
Modal.createDialog(ErrorDialog, {
|
||||||
|
title: "Failed to join room",
|
||||||
|
description: msg
|
||||||
|
});
|
||||||
});
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
joining: true
|
joining: true
|
||||||
|
@ -712,7 +736,7 @@ module.exports = React.createClass({
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|
||||||
uploadNewState: function(new_name, new_topic, new_join_rule, new_history_visibility, new_power_levels) {
|
uploadNewState: function(newVals) {
|
||||||
var old_name = this.state.room.name;
|
var old_name = this.state.room.name;
|
||||||
|
|
||||||
var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
|
var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
|
||||||
|
@ -738,46 +762,54 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
var deferreds = [];
|
var deferreds = [];
|
||||||
|
|
||||||
if (old_name != new_name && new_name != undefined && new_name) {
|
if (old_name != newVals.name && newVals.name != undefined && newVals.name) {
|
||||||
deferreds.push(
|
deferreds.push(
|
||||||
MatrixClientPeg.get().setRoomName(this.state.room.roomId, new_name)
|
MatrixClientPeg.get().setRoomName(this.state.room.roomId, newVals.name)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_topic != new_topic && new_topic != undefined) {
|
if (old_topic != newVals.topic && newVals.topic != undefined) {
|
||||||
deferreds.push(
|
deferreds.push(
|
||||||
MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, new_topic)
|
MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, newVals.topic)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_join_rule != new_join_rule && new_join_rule != undefined) {
|
if (old_join_rule != newVals.join_rule && newVals.join_rule != undefined) {
|
||||||
deferreds.push(
|
deferreds.push(
|
||||||
MatrixClientPeg.get().sendStateEvent(
|
MatrixClientPeg.get().sendStateEvent(
|
||||||
this.state.room.roomId, "m.room.join_rules", {
|
this.state.room.roomId, "m.room.join_rules", {
|
||||||
join_rule: new_join_rule,
|
join_rule: newVals.join_rule,
|
||||||
}, ""
|
}, ""
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_history_visibility != new_history_visibility && new_history_visibility != undefined) {
|
if (old_history_visibility != newVals.history_visibility &&
|
||||||
|
newVals.history_visibility != undefined) {
|
||||||
deferreds.push(
|
deferreds.push(
|
||||||
MatrixClientPeg.get().sendStateEvent(
|
MatrixClientPeg.get().sendStateEvent(
|
||||||
this.state.room.roomId, "m.room.history_visibility", {
|
this.state.room.roomId, "m.room.history_visibility", {
|
||||||
history_visibility: new_history_visibility,
|
history_visibility: newVals.history_visibility,
|
||||||
}, ""
|
}, ""
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_power_levels) {
|
if (newVals.power_levels) {
|
||||||
deferreds.push(
|
deferreds.push(
|
||||||
MatrixClientPeg.get().sendStateEvent(
|
MatrixClientPeg.get().sendStateEvent(
|
||||||
this.state.room.roomId, "m.room.power_levels", new_power_levels, ""
|
this.state.room.roomId, "m.room.power_levels", newVals.power_levels, ""
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deferreds.push(
|
||||||
|
MatrixClientPeg.get().setGuestAccess(this.state.room.roomId, {
|
||||||
|
allowRead: newVals.guest_read,
|
||||||
|
allowJoin: newVals.guest_join
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
if (deferreds.length) {
|
if (deferreds.length) {
|
||||||
var self = this;
|
var self = this;
|
||||||
q.all(deferreds).fail(function(err) {
|
q.all(deferreds).fail(function(err) {
|
||||||
|
@ -862,19 +894,15 @@ module.exports = React.createClass({
|
||||||
uploadingRoomSettings: true,
|
uploadingRoomSettings: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var new_name = this.refs.header.getRoomName();
|
this.uploadNewState({
|
||||||
var new_topic = this.refs.room_settings.getTopic();
|
name: this.refs.header.getRoomName(),
|
||||||
var new_join_rule = this.refs.room_settings.getJoinRules();
|
topic: this.refs.room_settings.getTopic(),
|
||||||
var new_history_visibility = this.refs.room_settings.getHistoryVisibility();
|
join_rule: this.refs.room_settings.getJoinRules(),
|
||||||
var new_power_levels = this.refs.room_settings.getPowerLevels();
|
history_visibility: this.refs.room_settings.getHistoryVisibility(),
|
||||||
|
power_levels: this.refs.room_settings.getPowerLevels(),
|
||||||
this.uploadNewState(
|
guest_join: this.refs.room_settings.canGuestsJoin(),
|
||||||
new_name,
|
guest_read: this.refs.room_settings.canGuestsRead()
|
||||||
new_topic,
|
});
|
||||||
new_join_rule,
|
|
||||||
new_history_visibility,
|
|
||||||
new_power_levels
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancelClick: function() {
|
onCancelClick: function() {
|
||||||
|
|
|
@ -135,6 +135,12 @@ module.exports = React.createClass({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onUpgradeClicked: function() {
|
||||||
|
dis.dispatch({
|
||||||
|
action: "start_upgrade_registration"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onLogoutPromptCancel: function() {
|
onLogoutPromptCancel: function() {
|
||||||
this.logoutModal.closeDialog();
|
this.logoutModal.closeDialog();
|
||||||
},
|
},
|
||||||
|
@ -164,6 +170,28 @@ module.exports = React.createClass({
|
||||||
this.state.avatarUrl ? MatrixClientPeg.get().mxcUrlToHttp(this.state.avatarUrl) : null
|
this.state.avatarUrl ? MatrixClientPeg.get().mxcUrlToHttp(this.state.avatarUrl) : null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var accountJsx;
|
||||||
|
|
||||||
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
|
accountJsx = (
|
||||||
|
<div className="mx_UserSettings_button" onClick={this.onUpgradeClicked}>
|
||||||
|
Upgrade (It's free!)
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
accountJsx = (
|
||||||
|
<ChangePassword
|
||||||
|
className="mx_UserSettings_accountTable"
|
||||||
|
rowClassName="mx_UserSettings_profileTableRow"
|
||||||
|
rowLabelClassName="mx_UserSettings_profileLabelCell"
|
||||||
|
rowInputClassName="mx_UserSettings_profileInputCell"
|
||||||
|
buttonClassName="mx_UserSettings_button"
|
||||||
|
onError={this.onPasswordChangeError}
|
||||||
|
onFinished={this.onPasswordChanged} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_UserSettings">
|
<div className="mx_UserSettings">
|
||||||
<RoomHeader simpleHeader="Settings" />
|
<RoomHeader simpleHeader="Settings" />
|
||||||
|
@ -213,14 +241,7 @@ module.exports = React.createClass({
|
||||||
<h2>Account</h2>
|
<h2>Account</h2>
|
||||||
|
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
<ChangePassword
|
{accountJsx}
|
||||||
className="mx_UserSettings_accountTable"
|
|
||||||
rowClassName="mx_UserSettings_profileTableRow"
|
|
||||||
rowLabelClassName="mx_UserSettings_profileLabelCell"
|
|
||||||
rowInputClassName="mx_UserSettings_profileInputCell"
|
|
||||||
buttonClassName="mx_UserSettings_button"
|
|
||||||
onError={this.onPasswordChangeError}
|
|
||||||
onFinished={this.onPasswordChanged} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx_UserSettings_logout">
|
<div className="mx_UserSettings_logout">
|
||||||
|
|
|
@ -19,7 +19,6 @@ limitations under the License.
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var sdk = require('../../../index');
|
var sdk = require('../../../index');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
|
||||||
var dis = require('../../../dispatcher');
|
var dis = require('../../../dispatcher');
|
||||||
var Signup = require("../../../Signup");
|
var Signup = require("../../../Signup");
|
||||||
var ServerConfig = require("../../views/login/ServerConfig");
|
var ServerConfig = require("../../views/login/ServerConfig");
|
||||||
|
@ -40,6 +39,9 @@ module.exports = React.createClass({
|
||||||
hsUrl: React.PropTypes.string,
|
hsUrl: React.PropTypes.string,
|
||||||
isUrl: React.PropTypes.string,
|
isUrl: React.PropTypes.string,
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
|
username: React.PropTypes.string,
|
||||||
|
guestAccessToken: React.PropTypes.string,
|
||||||
|
disableUsernameChanges: React.PropTypes.bool,
|
||||||
// registration shouldn't know or care how login is done.
|
// registration shouldn't know or care how login is done.
|
||||||
onLoginClick: React.PropTypes.func.isRequired
|
onLoginClick: React.PropTypes.func.isRequired
|
||||||
},
|
},
|
||||||
|
@ -63,6 +65,7 @@ module.exports = React.createClass({
|
||||||
this.registerLogic.setSessionId(this.props.sessionId);
|
this.registerLogic.setSessionId(this.props.sessionId);
|
||||||
this.registerLogic.setRegistrationUrl(this.props.registrationUrl);
|
this.registerLogic.setRegistrationUrl(this.props.registrationUrl);
|
||||||
this.registerLogic.setIdSid(this.props.idSid);
|
this.registerLogic.setIdSid(this.props.idSid);
|
||||||
|
this.registerLogic.setGuestAccessToken(this.props.guestAccessToken);
|
||||||
this.registerLogic.recheckState();
|
this.registerLogic.recheckState();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -186,7 +189,9 @@ module.exports = React.createClass({
|
||||||
registerStep = (
|
registerStep = (
|
||||||
<RegistrationForm
|
<RegistrationForm
|
||||||
showEmail={true}
|
showEmail={true}
|
||||||
|
defaultUsername={this.props.username}
|
||||||
defaultEmail={this.props.email}
|
defaultEmail={this.props.email}
|
||||||
|
disableUsernameChanges={this.props.disableUsernameChanges}
|
||||||
minPasswordLength={MIN_PASSWORD_LENGTH}
|
minPasswordLength={MIN_PASSWORD_LENGTH}
|
||||||
onError={this.onFormValidationFailed}
|
onError={this.onFormValidationFailed}
|
||||||
onRegisterClick={this.onFormSubmit} />
|
onRegisterClick={this.onFormSubmit} />
|
||||||
|
|
|
@ -30,6 +30,7 @@ module.exports = React.createClass({
|
||||||
defaultUsername: React.PropTypes.string,
|
defaultUsername: React.PropTypes.string,
|
||||||
showEmail: React.PropTypes.bool,
|
showEmail: React.PropTypes.bool,
|
||||||
minPasswordLength: React.PropTypes.number,
|
minPasswordLength: React.PropTypes.number,
|
||||||
|
disableUsernameChanges: React.PropTypes.bool,
|
||||||
onError: React.PropTypes.func,
|
onError: React.PropTypes.func,
|
||||||
onRegisterClick: React.PropTypes.func // onRegisterClick(Object) => ?Promise
|
onRegisterClick: React.PropTypes.func // onRegisterClick(Object) => ?Promise
|
||||||
},
|
},
|
||||||
|
@ -109,7 +110,8 @@ module.exports = React.createClass({
|
||||||
{emailSection}
|
{emailSection}
|
||||||
<br />
|
<br />
|
||||||
<input className="mx_Login_field" type="text" ref="username"
|
<input className="mx_Login_field" type="text" ref="username"
|
||||||
placeholder="User name" defaultValue={this.state.username} />
|
placeholder="User name" defaultValue={this.state.username}
|
||||||
|
disabled={this.props.disableUsernameChanges} />
|
||||||
<br />
|
<br />
|
||||||
<input className="mx_Login_field" type="password" ref="password"
|
<input className="mx_Login_field" type="password" ref="password"
|
||||||
placeholder="Password" defaultValue={this.state.password} />
|
placeholder="Password" defaultValue={this.state.password} />
|
||||||
|
|
|
@ -31,6 +31,14 @@ module.exports = React.createClass({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
canGuestsJoin: function() {
|
||||||
|
return this.refs.guests_join.checked;
|
||||||
|
},
|
||||||
|
|
||||||
|
canGuestsRead: function() {
|
||||||
|
return this.refs.guests_read.checked;
|
||||||
|
},
|
||||||
|
|
||||||
getTopic: function() {
|
getTopic: function() {
|
||||||
return this.refs.topic.value;
|
return this.refs.topic.value;
|
||||||
},
|
},
|
||||||
|
@ -83,6 +91,10 @@ module.exports = React.createClass({
|
||||||
if (history_visibility) history_visibility = history_visibility.getContent().history_visibility;
|
if (history_visibility) history_visibility = history_visibility.getContent().history_visibility;
|
||||||
|
|
||||||
var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
|
var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
|
||||||
|
var guest_access = this.props.room.currentState.getStateEvents('m.room.guest_access', '');
|
||||||
|
if (guest_access) {
|
||||||
|
guest_access = guest_access.getContent().guest_access;
|
||||||
|
}
|
||||||
|
|
||||||
var events_levels = power_levels.events || {};
|
var events_levels = power_levels.events || {};
|
||||||
|
|
||||||
|
@ -154,6 +166,14 @@ module.exports = React.createClass({
|
||||||
<textarea className="mx_RoomSettings_description" placeholder="Topic" defaultValue={topic} ref="topic"/> <br/>
|
<textarea className="mx_RoomSettings_description" placeholder="Topic" defaultValue={topic} ref="topic"/> <br/>
|
||||||
<label><input type="checkbox" ref="is_private" defaultChecked={join_rule != "public"}/> Make this room private</label> <br/>
|
<label><input type="checkbox" ref="is_private" defaultChecked={join_rule != "public"}/> Make this room private</label> <br/>
|
||||||
<label><input type="checkbox" ref="share_history" defaultChecked={history_visibility == "shared"}/> Share message history with new users</label> <br/>
|
<label><input type="checkbox" ref="share_history" defaultChecked={history_visibility == "shared"}/> Share message history with new users</label> <br/>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" ref="guests_read" defaultChecked={history_visibility === "world_readable"}/>
|
||||||
|
Allow guests to read messages in this room
|
||||||
|
</label> <br/>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" ref="guests_join" defaultChecked={guest_access === "can_join"}/>
|
||||||
|
Allow guests to join this room
|
||||||
|
</label> <br/>
|
||||||
<label className="mx_RoomSettings_encrypt"><input type="checkbox" /> Encrypt room</label> <br/>
|
<label className="mx_RoomSettings_encrypt"><input type="checkbox" /> Encrypt room</label> <br/>
|
||||||
|
|
||||||
<h3>Power levels</h3>
|
<h3>Power levels</h3>
|
||||||
|
|
Loading…
Reference in a new issue