mirror of https://github.com/watcha-fr/synapse
commit
d12feed623
@ -0,0 +1,42 @@ |
|||||||
|
# Copyright 2014 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. |
||||||
|
|
||||||
|
from ._base import Config |
||||||
|
|
||||||
|
class CaptchaConfig(Config): |
||||||
|
|
||||||
|
def __init__(self, args): |
||||||
|
super(CaptchaConfig, self).__init__(args) |
||||||
|
self.recaptcha_private_key = args.recaptcha_private_key |
||||||
|
self.enable_registration_captcha = args.enable_registration_captcha |
||||||
|
self.captcha_ip_origin_is_x_forwarded = args.captcha_ip_origin_is_x_forwarded |
||||||
|
|
||||||
|
@classmethod |
||||||
|
def add_arguments(cls, parser): |
||||||
|
super(CaptchaConfig, cls).add_arguments(parser) |
||||||
|
group = parser.add_argument_group("recaptcha") |
||||||
|
group.add_argument( |
||||||
|
"--recaptcha-private-key", type=str, default="YOUR_PRIVATE_KEY", |
||||||
|
help="The matching private key for the web client's public key." |
||||||
|
) |
||||||
|
group.add_argument( |
||||||
|
"--enable-registration-captcha", type=bool, default=False, |
||||||
|
help="Enables ReCaptcha checks when registering, preventing signup "+ |
||||||
|
"unless a captcha is answered. Requires a valid ReCaptcha public/private key." |
||||||
|
) |
||||||
|
group.add_argument( |
||||||
|
"--captcha_ip_origin_is_x_forwarded", type=bool, default=False, |
||||||
|
help="When checking captchas, use the X-Forwarded-For (XFF) header as the client IP "+ |
||||||
|
"and not the actual client IP." |
||||||
|
) |
@ -0,0 +1,27 @@ |
|||||||
|
/* Copyright 2014 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS room_aliases_alias ON room_aliases(room_alias); |
||||||
|
CREATE INDEX IF NOT EXISTS room_aliases_id ON room_aliases(room_id); |
||||||
|
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS room_alias_servers_alias ON room_alias_servers(room_alias); |
||||||
|
|
||||||
|
DELETE FROM room_aliases WHERE rowid NOT IN (SELECT max(rowid) FROM room_aliases GROUP BY room_alias, room_id); |
||||||
|
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS room_aliases_uniq ON room_aliases(room_alias, room_id); |
||||||
|
|
||||||
|
PRAGMA user_version = 3; |
@ -0,0 +1,46 @@ |
|||||||
|
Captcha can be enabled for this web client / home server. This file explains how to do that. |
||||||
|
The captcha mechanism used is Google's ReCaptcha. This requires API keys from Google. |
||||||
|
|
||||||
|
Getting keys |
||||||
|
------------ |
||||||
|
Requires a public/private key pair from: |
||||||
|
|
||||||
|
https://developers.google.com/recaptcha/ |
||||||
|
|
||||||
|
|
||||||
|
Setting Private ReCaptcha Key |
||||||
|
----------------------------- |
||||||
|
The private key is a config option on the home server config. If it is not |
||||||
|
visible, you can generate it via --generate-config. Set the following value: |
||||||
|
|
||||||
|
recaptcha_private_key: YOUR_PRIVATE_KEY |
||||||
|
|
||||||
|
In addition, you MUST enable captchas via: |
||||||
|
|
||||||
|
enable_registration_captcha: true |
||||||
|
|
||||||
|
Setting Public ReCaptcha Key |
||||||
|
---------------------------- |
||||||
|
The web client will look for the global variable webClientConfig for config |
||||||
|
options. You should put your ReCaptcha public key there like so: |
||||||
|
|
||||||
|
webClientConfig = { |
||||||
|
useCaptcha: true, |
||||||
|
recaptcha_public_key: "YOUR_PUBLIC_KEY" |
||||||
|
} |
||||||
|
|
||||||
|
This should be put in webclient/config.js which is already .gitignored, rather |
||||||
|
than in the web client source files. You MUST set useCaptcha to true else a |
||||||
|
ReCaptcha widget will not be generated. |
||||||
|
|
||||||
|
Configuring IP used for auth |
||||||
|
---------------------------- |
||||||
|
The ReCaptcha API requires that the IP address of the user who solved the |
||||||
|
captcha is sent. If the client is connecting through a proxy or load balancer, |
||||||
|
it may be required to use the X-Forwarded-For (XFF) header instead of the origin |
||||||
|
IP address. This can be configured as an option on the home server like so: |
||||||
|
|
||||||
|
captcha_ip_origin_is_x_forwarded: true |
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,12 +1,13 @@ |
|||||||
Basic Usage |
Basic Usage |
||||||
----------- |
----------- |
||||||
|
|
||||||
The Synapse web client needs to be hosted by a basic HTTP server. |
The web client should automatically run when running the home server. Alternatively, you can run |
||||||
|
it stand-alone: |
||||||
You can use the Python simple HTTP server:: |
|
||||||
|
|
||||||
$ python -m SimpleHTTPServer |
$ python -m SimpleHTTPServer |
||||||
|
|
||||||
Then, open this URL in a WEB browser:: |
Then, open this URL in a WEB browser:: |
||||||
|
|
||||||
http://127.0.0.1:8000/ |
http://127.0.0.1:8000/ |
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,135 @@ |
|||||||
|
/* |
||||||
|
Copyright 2014 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
'use strict'; |
||||||
|
|
||||||
|
angular.module('matrixFilter', []) |
||||||
|
|
||||||
|
// Compute the room name according to information we have
|
||||||
|
.filter('mRoomName', ['$rootScope', 'matrixService', function($rootScope, matrixService) { |
||||||
|
return function(room_id) { |
||||||
|
var roomName; |
||||||
|
|
||||||
|
// If there is an alias, use it
|
||||||
|
// TODO: only one alias is managed for now
|
||||||
|
var alias = matrixService.getRoomIdToAliasMapping(room_id); |
||||||
|
if (alias) { |
||||||
|
roomName = alias; |
||||||
|
} |
||||||
|
|
||||||
|
if (undefined === roomName) { |
||||||
|
// Else, build the name from its users
|
||||||
|
var room = $rootScope.events.rooms[room_id]; |
||||||
|
if (room) { |
||||||
|
var room_name_event = room["m.room.name"]; |
||||||
|
|
||||||
|
if (room_name_event) { |
||||||
|
roomName = room_name_event.content.name; |
||||||
|
} |
||||||
|
else if (room.members) { |
||||||
|
// Limit the room renaming to 1:1 room
|
||||||
|
if (2 === Object.keys(room.members).length) { |
||||||
|
for (var i in room.members) { |
||||||
|
var member = room.members[i]; |
||||||
|
if (member.state_key !== matrixService.config().user_id) { |
||||||
|
|
||||||
|
if (member.state_key in $rootScope.presence) { |
||||||
|
// If the user is available in presence, use the displayname there
|
||||||
|
// as it is the most uptodate
|
||||||
|
roomName = $rootScope.presence[member.state_key].content.displayname; |
||||||
|
} |
||||||
|
else if (member.content.displayname) { |
||||||
|
roomName = member.content.displayname; |
||||||
|
} |
||||||
|
else { |
||||||
|
roomName = member.state_key; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else if (1 === Object.keys(room.members).length) { |
||||||
|
// The other member may be in the invite list, get all invited users
|
||||||
|
var invitedUserIDs = []; |
||||||
|
for (var i in room.messages) { |
||||||
|
var message = room.messages[i]; |
||||||
|
if ("m.room.member" === message.type && "invite" === message.membership) { |
||||||
|
// Make sure there is no duplicate user
|
||||||
|
if (-1 === invitedUserIDs.indexOf(message.state_key)) { |
||||||
|
invitedUserIDs.push(message.state_key); |
||||||
|
} |
||||||
|
}
|
||||||
|
} |
||||||
|
|
||||||
|
// For now, only 1:1 room needs to be renamed. It means only 1 invited user
|
||||||
|
if (1 === invitedUserIDs.length) { |
||||||
|
var userID = invitedUserIDs[0]; |
||||||
|
|
||||||
|
// Try to resolve his displayname in presence global data
|
||||||
|
if (userID in $rootScope.presence) { |
||||||
|
roomName = $rootScope.presence[userID].content.displayname; |
||||||
|
} |
||||||
|
else { |
||||||
|
roomName = userID; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (undefined === roomName) { |
||||||
|
// By default, use the room ID
|
||||||
|
roomName = room_id; |
||||||
|
} |
||||||
|
|
||||||
|
return roomName; |
||||||
|
}; |
||||||
|
}]) |
||||||
|
|
||||||
|
// Compute the user display name in a room according to the data already downloaded
|
||||||
|
.filter('mUserDisplayName', ['$rootScope', function($rootScope) { |
||||||
|
return function(user_id, room_id) { |
||||||
|
var displayName; |
||||||
|
|
||||||
|
// Try to find the user name among presence data
|
||||||
|
// Warning: that means we have received before a presence event for this
|
||||||
|
// user which cannot be guaranted.
|
||||||
|
// However, if we get the info by this way, we are sure this is the latest user display name
|
||||||
|
// See FIXME comment below
|
||||||
|
if (user_id in $rootScope.presence) { |
||||||
|
displayName = $rootScope.presence[user_id].content.displayname; |
||||||
|
} |
||||||
|
|
||||||
|
// FIXME: Would like to use the display name as defined in room members of the room.
|
||||||
|
// But this information is the display name of the user when he has joined the room.
|
||||||
|
// It does not take into account user display name update
|
||||||
|
if (room_id) { |
||||||
|
var room = $rootScope.events.rooms[room_id]; |
||||||
|
if (room && (user_id in room.members)) { |
||||||
|
var member = room.members[user_id]; |
||||||
|
if (member.content.displayname) { |
||||||
|
displayName = member.content.displayname; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (undefined === displayName) { |
||||||
|
// By default, use the user ID
|
||||||
|
displayName = user_id; |
||||||
|
} |
||||||
|
return displayName; |
||||||
|
}; |
||||||
|
}]); |
After Width: | Height: | Size: 434 B |
After Width: | Height: | Size: 378 B |
Loading…
Reference in new issue