12 Commits

Author SHA1 Message Date
fe504f7ad7 Merge branch 'master' of github.com:/krombel/matrix-register-bot 2018-04-24 15:28:17 +02:00
d130ba30c8 autoformatting 2018-04-24 15:27:17 +02:00
0ff9108220 Introduce cron.php 2018-04-24 15:02:05 +02:00
d9e65f4b5d make cleanup of database database independent 2018-04-24 14:55:40 +02:00
a6ce908f4b implement operationMode in cron.php 2018-04-24 14:21:03 +02:00
0a21e01540 implement database cleanup of registrations 2018-04-24 14:20:42 +02:00
629ead76e2 internationalize strings used in cron.php 2018-04-24 14:20:21 +02:00
d597a54353 implement usage of __DIR__ to fix references on include 2018-04-24 13:35:33 +02:00
0c1141dbb9 Update README to explain thecurrent feature set
- add note to require php to be able to send mails
- explain operationMode
2018-04-18 17:03:20 +02:00
31ab9b816b Add link to matrix room 2018-04-16 15:41:35 +02:00
be88dfdc3d fix config.sample 2018-04-16 15:18:55 +02:00
Matthias
2c524ed066 implementing multiple modes for operation
implement operationModes:
- local: With local database
- synapse: use register-API of synapse
2018-04-16 15:17:12 +02:00
16 changed files with 233 additions and 169 deletions

View File

@@ -1,28 +1,34 @@
# matrix-register-bot # matrix-register-bot
This bot provides a two-step-registration for matrix. This bot provides a two-step-registration for matrix ([synapse](https://github.com/matrix-org/synapse)).
This is done in several steps: This is done in several steps:
- potential new user registers on a bot-provided side - potential new user registers on a bot-provided site
- user has to verify its mail address
- bot sends a message to predefined room with a registration notification. - bot sends a message to predefined room with a registration notification.
- users in that room now can approve or decline the registration. - users in that room now can approve or decline the registration.
- When approved - When approved
- the bot creates credentials - the bot creates short time credentials
- sends them to the user - sends them to the user
- stores them encrypted in own database - stores them encrypted in own databas or uses that as initial password for registration
- provides that credentials to [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth#integrate) which has to be configured to query login.php
2nd step: Implement the other apis to integrade [mxisd](https://github.com/kamax-io/mxisd/blob/master/docs/backends/rest.md) To configure synapse so that the users can login that were created via this bot you can either
- set `operationMode=synapse` so the bot uses the register api to push the new users to synapse or
- integrate it via [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth#integrate) by configuring your system to point at `internal/login.php`.
When using `operationMode=local` you can have the following benefits (some require [mxisd](https://github.com/kamax-io/mxisd/blob/master/docs/backends/rest.md))
- Automatically set the display name based on first and last name on first login
- Use the 3PID lookup for other users (only email)
- Search for users that you have not seen yet
This bot takes care for user accounts. So it stores the credentials itself and provides ways to access them via matrix-synapse-rest-auth or mxisd.
## How to install ## How to install
- Copy `config.sample.php` to `config.php` and configure the bot as you can find there - Copy `config.sample.php` to `config.php` and configure the bot as you can find there
- Configure your webserver to publish the folder `public`. - Configure your webserver to have the folder `public` accessible via web.
The folder `internal` contains files that can be accessed by mxisd or matrix-synapse-rest-auth or else via a reverse proxy The folder `internal` contains files that only provide API access. They can be accessed by mxisd or matrix-synapse-rest-auth
- To integrate with [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth): - To integrate with [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth):
- `/_matrix-internal/identity/v1/check_credentials` should map to `internal/login.php` - `/_matrix-internal/identity/v1/check_credentials` should map to `internal/login.php`
- To integrate with [mxisd](https://github.com/kamax-io/mxisd): Have a look at [the docs](https://github.com/kamax-io/mxisd/blob/master/docs/backends/rest.md) and apply as follows: - To integrate with [mxisd](https://github.com/kamax-io/mxisd): Have a look at [the docs of mxisd](https://github.com/kamax-io/mxisd/blob/master/docs/backends/rest.md) and apply as follows:
| Key | file which handles that | Description | | Key | file which handles that | Description |
@@ -33,15 +39,25 @@ This bot takes care for user accounts. So it stores the credentials itself and p
| rest.endpoints.identity.bulk | internal/identity_bulk.php | Endpoint to query a list of 3PID | | rest.endpoints.identity.bulk | internal/identity_bulk.php | Endpoint to query a list of 3PID |
## Implement usage of additional features: ## Further notes:
### Use the ChangePasswortInterceptor:
You need a reverse proxy which maps `/_matrix/client/r0/account/password` to `internal/intercept_change_password.php`. ### This bot sends mails
To allow the bot to verify the email address of the user and to interact with them e.g. in case of approval this bot needs a running mailserver configuration.
This bot relies on php to be properly configured.
### Use the ChangePasswortInterceptor (if `operationMode=local`)
To allow users to change their pasword you need a reverse proxy which maps `/_matrix/client/r0/account/password` to `internal/intercept_change_password.php`.
Here is an example for nginx: Here is an example for nginx:
``` ```
location /_matrix/client/r0/account/password { location /_matrix/client/r0/account/password {
proxy_pass http://localhost/mxbot/internal/intercept_change_password.php; proxy_pass http://localhost/mxbot/internal/intercept_change_password.php;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
} }
``` ```
### The bot postpones some actions
There is a cron.php which implements retries and database cleanups (e.g. to remove a username claim)
For this run cron.php regularly with your system of choice.
### Chat
For further questions, comments, feedback and more come and talk in [#matrix-register-bot:msg-net.de](https://matrix.to/#/#matrix-register-bot:msg-net.de)

View File

@@ -14,17 +14,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("config.php"); require_once(__DIR__ . "/config.php");
require_once("mail_templates.php"); require_once(__DIR__ . "/language.php");
require_once("database.php"); require_once(__DIR__ . "/mail_templates.php");
require_once(__DIR__ . "/database.php");
$sql = "SELECT id, first_name, last_name, username, email, state, note, verify_token, admin_token FROM registrations " $sql = "SELECT id, first_name, last_name, username, email, state, note, verify_token, admin_token FROM registrations "
. "WHERE state = " . RegisterState::PendingEmailSend . "WHERE state = " . RegisterState::PendingEmailSend
. " OR state = " . RegisterState::PendingAdminSend . " OR state = " . RegisterState::PendingAdminSend
. " OR state = " . RegisterState::PendingRegistration . " OR state = " . RegisterState::PendingRegistration
. " OR state = " . RegisterState::PendingSendRegistrationMail . " OR state = " . RegisterState::PendingSendRegistrationMail . ";";
. " OR state = " . RegisterState::RegistrationDeclined
. " OR state = " . RegisterState::AllDone . ";";
foreach ($mx_db->query($sql) as $row) { foreach ($mx_db->query($sql) as $row) {
$first_name = $row["first_name"]; $first_name = $row["first_name"];
$last_name = $row["last_name"]; $last_name = $row["last_name"];
@@ -46,16 +45,22 @@ foreach ($mx_db->query($sql) as $row) {
} }
break; break;
case RegisterState::PendingAdminSend: case RegisterState::PendingAdminSend:
require_once("MatrixConnection.php"); require_once(__DIR__ . "/MatrixConnection.php");
$adminUrl = $config["webroot"] . "/verify_admin.php?t=" . $row["admin_token"]; $adminUrl = $config["webroot"] . "/verify_admin.php?t=" . $row["admin_token"];
$mxConn = new MatrixConnection($config["homeserver"], $config["access_token"]); $mxConn = new MatrixConnection($config["homeserver"], $config["access_token"]);
$mxMsg = new MatrixMessage(); $mxMsg = new MatrixMessage();
$mxMsg->set_body($first_name . ' ' . $last_name . " möchte sich registrieren und hat folgende Notiz hinterlassen:\r\n" $mxMsg->set_body(strtr($language["MSG_USER_WANTS_REGISTER"], [
. $row["note"] . "\r\n" "@name" => (strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username),
. "Zum Bearbeiten hier klicken:\r\n" . $adminUrl); "@note" => $note,
$mxMsg->set_formatted_body($first_name . ' ' . $last_name . " möchte sich registrieren und hat folgende Notiz hinterlassen:<br />" "@adminUrl" => $adminUrl
. $row["note"] . "<br />" ]));
. "Zum Bearbeiten <a href=\"" . $adminUrl . "\">hier</a> klicken"); if (isset($language["MSG_USER_WANTS_REGISTER_FORMATTED"])) {
$mxMsg->set_formatted_body(strtr($language["MSG_USER_WANTS_REGISTER_FORMATTED"], [
"@name" => (strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username),
"@note" => $note,
"@adminUrl" => $adminUrl
]));
}
$mxMsg->set_type("m.text"); $mxMsg->set_type("m.text");
$response = $mxConn->send($config["register_room"], $mxMsg); $response = $mxConn->send($config["register_room"], $mxMsg);
@@ -69,11 +74,29 @@ foreach ($mx_db->query($sql) as $row) {
break; break;
case RegisterState::PendingRegistration: case RegisterState::PendingRegistration:
// Registration got accepted but registration failed // Registration got accepted but registration failed
switch ($config["operationMode"]) {
$password = $mx_db->addUser($row["first_name"], $row["last_name"], $row["username"], $row["email"]); case "synapse":
// register with registration_shared_secret
// generate a password with 10 characters
$password = bin2hex(openssl_random_pseudo_bytes(5));
$res = $mxConn->register($row["username"], $password, $config["registration_shared_secret"]);
if (!$res) {
// something went wrong while registering
$password = NULL;
}
break;
case "local":
// register by adding a user to the local database
$password = $mx_db->addUser($row["first_name"], $row["last_name"], $row["username"], $row["email"]);
break;
default:
throw new Exception("Unknown operationMode");
}
if ($password != NULL) { if ($password != NULL) {
// send registration_success // send registration_success
$res = send_mail_registration_success($config["homeserver"], $first_name . " " . $last_name, $email, $username, $password, $config["howToURL"]); $res = send_mail_registration_success(
$config["homeserver"], strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username, $email, $username, $password, $config["howToURL"]
);
if ($res) { if ($res) {
$mx_db->setRegistrationStateById(RegisterState::AllDone, $row["id"]); $mx_db->setRegistrationStateById(RegisterState::AllDone, $row["id"]);
} else { } else {
@@ -83,7 +106,9 @@ foreach ($mx_db->query($sql) as $row) {
send_mail_registration_allowed_but_failed($config["homeserver"], $first_name . " " . $last_name, $email); send_mail_registration_allowed_but_failed($config["homeserver"], $first_name . " " . $last_name, $email);
$mxMsg = new MatrixMessage(); $mxMsg = new MatrixMessage();
$mxMsg->set_type("m.text"); $mxMsg->set_type("m.text");
$mxMsg->set_body("Fehler beim Registrieren von " . $first_name . " " . $last_name . "."); $mxMsg->set_body(strtr($language["REGISTRATION_FAILED_FOR"], [
"@name" => strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username,
]));
$mxConn->send($config["register_room"], $mxMsg); $mxConn->send($config["register_room"], $mxMsg);
throw new Exception($language["REGISTRATION_FAILED"]); throw new Exception($language["REGISTRATION_FAILED"]);
} }
@@ -91,14 +116,29 @@ foreach ($mx_db->query($sql) as $row) {
case RegisterState::PendingSendRegistrationMail: case RegisterState::PendingSendRegistrationMail:
print ("Error: Unhandled state: PendingSendRegistrationMail for " . $first_name . " " . $last_name . " (" . $username . ")\n"); print ("Error: Unhandled state: PendingSendRegistrationMail for " . $first_name . " " . $last_name . " (" . $username . ")\n");
break; break;
case RegisterState::RegistrationDeclined:
case RegisterState::AllDone:
// do reqular cleanup
break;
} }
} catch (Exception $e) { } catch (Exception $e) {
print("Error while handling cron for " . $first_name . " " . $last_name . " (" . $username . ")\n"); print("Error while handling cron for " . $first_name . " " . $last_name . " (" . $username . ")\n");
print($e->getMessage()); print($e->getMessage());
} }
} }
try {
//cleanup: all finished entries older than one month
$timestamp = date('Y-m-d H:m:s', strtotime("-1 month"));
$mx_db->query("DELETE FROM registrations "
. "WHERE request_date < '$timestamp'"
. " AND (state = " . RegisterState::RegistrationDeclined
. " OR state = " . RegisterState::AllDone . " );"
);
//cleanup: all entries which are pending email registration older than two days
$timestamp = date('Y-m-d H:m:s', strtotime("-2 days"));
$mx_db->query("DELETE FROM registrations "
. "WHERE request_date < '$timestamp'"
. " AND state = " . RegisterState::PendingEmailVerify . ";"
);
} catch (Exception $e) {
print("Error while database cleanup\n");
print($e->getMessage());
}
?> ?>

View File

@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("config.php"); require_once(__DIR__ . "/config.php");
if (!isset($config["databaseURI"])) { if (!isset($config["databaseURI"])) {
throw new Exception("malformed configuration: databaseURI not defined"); throw new Exception("malformed configuration: databaseURI not defined");
} }

View File

@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
$response = [ $response = [
"limited" => false, "limited" => false,
"result" => [], "result" => [],

View File

@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
$response = [ $response = [
"lookup" => [] "lookup" => []
]; ];

View File

@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
$response = new stdClass; $response = new stdClass;
try { try {
$inputJSON = file_get_contents('php://input'); $inputJSON = file_get_contents('php://input');

View File

@@ -44,14 +44,14 @@ try {
throw new Exception('"new_password" is not defined'); throw new Exception('"new_password" is not defined');
} }
require_once("../helpers.php"); require_once(__DIR__ . "/../helpers.php");
$localpart = stripLocalpart($input["auth"]["user"]); $localpart = stripLocalpart($input["auth"]["user"]);
if (empty($localpart)) { if (empty($localpart)) {
throw new Exception("localpart cannot be identified"); throw new Exception("localpart cannot be identified");
} }
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
if (!$mx_db->updatePassword( if (!$mx_db->updatePassword(
$localpart, $input["auth"]["password"], $input["new_password"] $localpart, $input["auth"]["password"], $input["new_password"]
)) { )) {

View File

@@ -20,7 +20,7 @@ $response = [
] ]
]; ];
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
abstract class LoginRequester { abstract class LoginRequester {
@@ -56,7 +56,7 @@ try {
// prefer the localpart attribute of mxisd. But in case of matrix-synapse-rest-auth // prefer the localpart attribute of mxisd. But in case of matrix-synapse-rest-auth
// we have to parse it on our own // we have to parse it on our own
if (empty($localpart)) { if (empty($localpart)) {
require_once("../helpers.php"); require_once(__DIR__ . "/../helpers.php");
$localpart = stripLocalpart($mxid); $localpart = stripLocalpart($mxid);
} }

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* Copyright 2018 Matthias Kesler * Copyright 2018 Matthias Kesler
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* Copyright 2018 Matthias Kesler * Copyright 2018 Matthias Kesler
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,15 +15,15 @@
* limitations under the License. * limitations under the License.
*/ */
function send_mail($receiver, $subject, $body) { function send_mail($receiver, $subject, $body) {
include("../config.php"); include(__DIR__ . "/../config.php");
$headers = "From: " . $config["register_email"] . "\r\n" $headers = "From: " . $config["register_email"] . "\r\n"
. "Content-Type: text/plain;charset=utf-8"; . "Content-Type: text/plain;charset=utf-8";
return mail($receiver, $subject, $body, $headers); return mail($receiver, $subject, $body, $headers);
} }
function send_mail_pending_verification($homeserver, $user, $receiver, $verify_url) { function send_mail_pending_verification($homeserver, $user, $receiver, $verify_url) {
$subject = "Bitte bestätige Registrierung auf $homeserver"; $subject = "Bitte bestätige Registrierung auf $homeserver";
$body = "Guten Tag " . $user . ", $body = "Guten Tag " . $user . ",
Du hast anscheinend versucht dich auf $homeserver zu registrieren. Du hast anscheinend versucht dich auf $homeserver zu registrieren.
Hier gibt es eine zweistufige Registrierung. Hier gibt es eine zweistufige Registrierung.
@@ -39,12 +40,12 @@ Danach ist eine Re-Registrierung mit deinem gewünschten Nutzernamen für andere
Vielen Dank für dein Verständnis. Vielen Dank für dein Verständnis.
Das Administratoren-Team von " . $homeserver; Das Administratoren-Team von " . $homeserver;
return send_mail($receiver, $subject, $body ); return send_mail($receiver, $subject, $body);
} }
function send_mail_pending_approval($homeserver, $user, $receiver) { function send_mail_pending_approval($homeserver, $user, $receiver) {
$subject = "Registrierung wartet auf Bestätigung durch Administratoren"; $subject = "Registrierung wartet auf Bestätigung durch Administratoren";
$body = "Guten Tag " . $user . ", $body = "Guten Tag " . $user . ",
Deine Registrierungsanfrage wurde verifiziert und wird nun durch die Administratoren überprüft. Deine Registrierungsanfrage wurde verifiziert und wird nun durch die Administratoren überprüft.
@@ -53,12 +54,12 @@ Du bekommst eine weitere E-Mail, sobald deine Registrierung bestätigt oder able
Vielen Dank für dein Verständnis. Vielen Dank für dein Verständnis.
Das Administratoren-Team von " . $homeserver; Das Administratoren-Team von " . $homeserver;
return send_mail($receiver, $subject, $body ); return send_mail($receiver, $subject, $body);
} }
function send_mail_registration_allowed_but_failed($homeserver, $user, $receiver) { function send_mail_registration_allowed_but_failed($homeserver, $user, $receiver) {
$subject = "Registrierung auf $homeserver genehmigt"; $subject = "Registrierung auf $homeserver genehmigt";
$body = "Guten Tag " . $user . ", $body = "Guten Tag " . $user . ",
Deine Registrierungsanfrage wurde durch die Administratoren bestätigt. Deine Registrierungsanfrage wurde durch die Administratoren bestätigt.
@@ -67,13 +68,12 @@ Wir hoffen, das Problem ist bald behoben.
Wir melden uns, wenn die Registrierung erfolgreich war. Wir melden uns, wenn die Registrierung erfolgreich war.
Das Administratoren-Team von " . $homeserver; Das Administratoren-Team von " . $homeserver;
return send_mail($receiver, $subject, $body); return send_mail($receiver, $subject, $body);
} }
function send_mail_registration_success($homeserver, $user, $receiver, $username, $password, $howToURL) { function send_mail_registration_success($homeserver, $user, $receiver, $username, $password, $howToURL) {
$subject = "Registrierung auf $homeserver erfolgreich"; $subject = "Registrierung auf $homeserver erfolgreich";
$body = "Guten Tag " . $user . ", $body = "Guten Tag " . $user . ",
Deine Registrierungsanfrage wurde durch die Administratoren bestätigt. Deine Registrierungsanfrage wurde durch die Administratoren bestätigt.
@@ -84,41 +84,42 @@ Passwort: $password
Hinweis: Das Passwort kannst du aktuell über die App selbst ändern. Auch wenn das Passwort nirgends Hinweis: Das Passwort kannst du aktuell über die App selbst ändern. Auch wenn das Passwort nirgends
im Klartext gespeichert wird, kann jemand Zugriff auf diese Mail erlangen und so den Zugriff bekommen. im Klartext gespeichert wird, kann jemand Zugriff auf diese Mail erlangen und so den Zugriff bekommen.
"; ";
/* /*
Wichtig: Bitte ändere das Passwort direkt nach der Anmeldung. Wichtig: Bitte ändere das Passwort direkt nach der Anmeldung.
Es wird zwar von unserer Seite nicht gespeichert, doch fremde könnten Zugriff auf diese E-Mail Es wird zwar von unserer Seite nicht gespeichert, doch fremde könnten Zugriff auf diese E-Mail
erhalten und so deinen Account kompromittieren. erhalten und so deinen Account kompromittieren.
*/ */
if (!empty($howToURL)) { if (!empty($howToURL)) {
$body .= " $body .= "
Zu weiteren Hilfestellungen findest du hier eine Auflistung von verschiedenen Zu weiteren Hilfestellungen findest du hier eine Auflistung von verschiedenen
Anleitungen zu verschiedenen Clients: Anleitungen zu verschiedenen Clients:
$howToURL\n"; $howToURL\n";
} }
$body .= " $body .= "
Viel Spaß bei der Verwendung von $homeserver. Viel Spaß bei der Verwendung von $homeserver.
Bei Fragen findest du nach der Anmeldung ein paar Räume in denen du sie stellen kannst. Bei Fragen findest du nach der Anmeldung ein paar Räume in denen du sie stellen kannst.
Das Administratoren-Team von " . $homeserver; Das Administratoren-Team von " . $homeserver;
return send_mail($receiver, $subject, $body); return send_mail($receiver, $subject, $body);
} }
function send_mail_registration_decline($homeserver, $user, $receiver, $reason) { function send_mail_registration_decline($homeserver, $user, $receiver, $reason) {
$subject = "Registrierung auf $homeserver abgelehnt"; $subject = "Registrierung auf $homeserver abgelehnt";
$body = "Guten Tag " . $user . ", $body = "Guten Tag " . $user . ",
Deine Registrierungsanfrage wurde durch die Administratoren abgelehnt.\n"; Deine Registrierungsanfrage wurde durch die Administratoren abgelehnt.\n";
if (empty($reason)) { if (empty($reason)) {
$body .= "\nEs wurde kein Grund angegeben\n"; $body .= "\nEs wurde kein Grund angegeben\n";
} else { } else {
$body .= "\nAls Grund wurde folgendes angegeben:\n$reason\n"; $body .= "\nAls Grund wurde folgendes angegeben:\n$reason\n";
} }
$body .= " $body .= "
Wir hoffen, dass du dies akzeptieren kannst. Wir hoffen, dass du dies akzeptieren kannst.
Das Administratoren-Team von " . $homeserver; Das Administratoren-Team von " . $homeserver;
return send_mail($receiver, $subject, $body ); return send_mail($receiver, $subject, $body);
} }
?> ?>

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* Copyright 2018 Matthias Kesler * Copyright 2018 Matthias Kesler
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,15 +15,15 @@
* limitations under the License. * limitations under the License.
*/ */
function send_mail($receiver, $subject, $body) { function send_mail($receiver, $subject, $body) {
include("../config.php"); include(__DIR__ . "/../config.php");
$headers = "From: " . $config["register_email"] . "\r\n" $headers = "From: " . $config["register_email"] . "\r\n"
. "Content-Type: text/plain;charset=utf-8"; . "Content-Type: text/plain;charset=utf-8";
return mail($receiver, $subject, $body, $headers); return mail($receiver, $subject, $body, $headers);
} }
function send_mail_pending_verification($homeserver, $user, $receiver, $verify_url) { function send_mail_pending_verification($homeserver, $user, $receiver, $verify_url) {
$subject = "Pleast approve your registration request on $homeserver"; $subject = "Pleast approve your registration request on $homeserver";
$body = "Dear " . $user . ", $body = "Dear " . $user . ",
It seems that you tried to register on $homeserver. It seems that you tried to register on $homeserver.
This homeserver requires a two step registration. This homeserver requires a two step registration.
@@ -38,12 +39,12 @@ Others might take your username afterwards.
Thanks for your patience. Thanks for your patience.
The admin team of " . $homeserver; The admin team of " . $homeserver;
return send_mail($receiver, $subject, $body ); return send_mail($receiver, $subject, $body);
} }
function send_mail_pending_approval($homeserver, $user, $receiver) { function send_mail_pending_approval($homeserver, $user, $receiver) {
$subject = "Registration is pending verification from an admin"; $subject = "Registration is pending verification from an admin";
$body = "Dear " . $user . ", $body = "Dear " . $user . ",
You have verified your registration request. The admins are now checking your request. You have verified your registration request. The admins are now checking your request.
@@ -52,12 +53,12 @@ You will get an email once they approve or decline your request.
Sincerely, Sincerely,
The admin team of " . $homeserver; The admin team of " . $homeserver;
return send_mail($receiver, $subject, $body ); return send_mail($receiver, $subject, $body);
} }
function send_mail_registration_allowed_but_failed($homeserver, $user, $receiver) { function send_mail_registration_allowed_but_failed($homeserver, $user, $receiver) {
$subject = "Registration on $homeserver got approved"; $subject = "Registration on $homeserver got approved";
$body = "Dear " . $user . ", $body = "Dear " . $user . ",
Your registration request got approved by the admin team. Your registration request got approved by the admin team.
@@ -66,13 +67,12 @@ We hope that the issue will be fixed soon.
You will get another email with initial credentials once the registration got handled completely. You will get another email with initial credentials once the registration got handled completely.
The admin team of " . $homeserver; The admin team of " . $homeserver;
return send_mail($receiver, $subject, $body); return send_mail($receiver, $subject, $body);
} }
function send_mail_registration_success($homeserver, $user, $receiver, $username, $password, $howToURL) { function send_mail_registration_success($homeserver, $user, $receiver, $username, $password, $howToURL) {
$subject = "Registration on $homeserver got approved"; $subject = "Registration on $homeserver got approved";
$body = "Dear " . $user . ", $body = "Dear " . $user . ",
Your registration request got verified by the admin team. Your registration request got verified by the admin team.
@@ -84,35 +84,36 @@ Important: Please change your password as soon as possible after your first logi
The password is not stored in clear text on the server but people could get access to this mail The password is not stored in clear text on the server but people could get access to this mail
and compromise your account. and compromise your account.
"; ";
if (!empty($howToURL)) { if (!empty($howToURL)) {
$body .= " $body .= "
You can find further help here:: You can find further help here::
$howToURL\n"; $howToURL\n";
} }
$body .= " $body .= "
Enjoy your usage of $homeserver. Enjoy your usage of $homeserver.
You can ask further questions inside of the chat system. You can ask further questions inside of the chat system.
The admin team of " . $homeserver; The admin team of " . $homeserver;
return send_mail($receiver, $subject, $body); return send_mail($receiver, $subject, $body);
} }
function send_mail_registration_decline($homeserver, $user, $receiver, $reason) { function send_mail_registration_decline($homeserver, $user, $receiver, $reason) {
$subject = "Registration on $homeserver declined."; $subject = "Registration on $homeserver declined.";
$body = "Guten Tag " . $user . ", $body = "Guten Tag " . $user . ",
Your registration request got declined by the admin team.\n"; Your registration request got declined by the admin team.\n";
if (empty($reason)) { if (empty($reason)) {
$body .= "\nThey did not provide any reason for this\n"; $body .= "\nThey did not provide any reason for this\n";
} else { } else {
$body .= "\nThey provide following hint for you:\n$reason\n"; $body .= "\nThey provide following hint for you:\n$reason\n";
} }
$body .= " $body .= "
We hope that you can understand this reason. We hope that you can understand this reason.
The admin team of " . $homeserver; The admin team of " . $homeserver;
return send_mail($receiver, $subject, $body ); return send_mail($receiver, $subject, $body);
} }
?> ?>

View File

@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("config.php"); require_once(__DIR__ . "/config.php");
$lang = $config["defaultLanguage"]; $lang = $config["defaultLanguage"];
if (isset($_GET['lang'])) { if (isset($_GET['lang'])) {
@@ -25,7 +25,7 @@ if (!file_exists($lang_file)) {
error_log("Translation for " . $lang . " not found. Fallback to 'de-de'"); error_log("Translation for " . $lang . " not found. Fallback to 'de-de'");
$lang = "de-de"; $lang = "de-de";
} }
$lang_file = dirname(__FILE__) . "/lang/lang." . $lang . ".php"; $lang_file = __DIR__ . "/lang/lang." . $lang . ".php";
require_once($lang_file); require_once($lang_file);
unset($lang_file); unset($lang_file);
?> ?>

View File

@@ -14,17 +14,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once("config.php"); require_once(__DIR__ . "/config.php");
$lang = $config["defaultLanguage"]; $lang = $config["defaultLanguage"];
if (isset($_GET['lang'])) { if (isset($_GET['lang'])) {
$lang = filter_var($_GET['lang'], FILTER_SANITIZE_STRING); $lang = filter_var($_GET['lang'], FILTER_SANITIZE_STRING);
} }
$lang_file = dirname(__FILE__) . "/lang/mail." . $lang . ".php"; $lang_file = __DIR__ . "/lang/mail." . $lang . ".php";
if (!file_exists($lang_file)) { if (!file_exists($lang_file)) {
error_log("Mail templates for '" . $lang . "' not found. Fallback to 'de-de'"); error_log("Mail templates for '" . $lang . "' not found. Fallback to 'de-de'");
$lang = "de-de"; $lang = "de-de";
} }
$lang_file = dirname(__FILE__) . "/lang/mail." . $lang . ".php"; $lang_file = __DIR__ . "/lang/mail." . $lang . ".php";
require_once($lang_file); require_once($lang_file);
unset($lang_file); unset($lang_file);
?> ?>

View File

@@ -19,12 +19,12 @@ if (!isset($_SERVER['HTTPS'])) {
exit(); exit();
} }
require_once "../language.php"; require_once(__DIR__ . "/../language.php");
if (!file_exists("../config.php")) { if (!file_exists("../config.php")) {
print($language["NO_CONFIGURATION"]); print($language["NO_CONFIGURATION"]);
exit(); exit();
} }
require_once "../config.php"; require_once(__DIR__ . "/../config.php");
// this values will not be used when using the register operation type // this values will not be used when using the register operation type
$storeFirstLastName = false; $storeFirstLastName = false;
@@ -86,7 +86,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
$note = filter_var($_POST["note"], FILTER_SANITIZE_STRING); $note = filter_var($_POST["note"], FILTER_SANITIZE_STRING);
$email = filter_var($_POST["email"], FILTER_VALIDATE_EMAIL); $email = filter_var($_POST["email"], FILTER_VALIDATE_EMAIL);
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
$res = $mx_db->addRegistration($first_name, $last_name, $username, $note, $email); $res = $mx_db->addRegistration($first_name, $last_name, $username, $note, $email);
if (!isset($res["verify_token"])) { if (!isset($res["verify_token"])) {
@@ -96,7 +96,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
$verify_token = $res["verify_token"]; $verify_token = $res["verify_token"];
$verify_url = $config["webroot"] . "/verify.php?t=" . $verify_token; $verify_url = $config["webroot"] . "/verify.php?t=" . $verify_token;
require_once "../mail_templates.php"; require_once(__DIR__ . "/../mail_templates.php");
$success = send_mail_pending_verification( $success = send_mail_pending_verification(
$config["homeserver"], $storeFirstLastName ? $first_name . " " . $last_name : $username, $email, $verify_url); $config["homeserver"], $storeFirstLastName ? $first_name . " " . $last_name : $username, $email, $verify_url);
@@ -122,7 +122,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
} else { } else {
$_SESSION["token"] = bin2hex(random_bytes(16)); $_SESSION["token"] = bin2hex(random_bytes(16));
?> ?>
<title><?php echo strtr($language["TOPIC_PLEASE_REGISTER"], [ "@homeserver" => $config["homeserver"] ]); ?></title> <title><?php echo strtr($language["TOPIC_PLEASE_REGISTER"], ["@homeserver" => $config["homeserver"]]); ?></title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet"> <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet">
<style> <style>
body{ body{
@@ -146,27 +146,29 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<div class="col-xs-12 col-sm-8 col-md-4 col-sm-offset-2 col-md-offset-4"> <div class="col-xs-12 col-sm-8 col-md-4 col-sm-offset-2 col-md-offset-4">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title"><?php echo strtr($language["TOPIC_PLEASE_REGISTER"], [ "@homeserver" => $config["homeserver"] ]) <h3 class="panel-title"><?php
. "<small>" . $language["TOPIC_PLEASE_REGISTER_NOTE"] . "</small>"; ?></h3> echo strtr($language["TOPIC_PLEASE_REGISTER"], ["@homeserver" => $config["homeserver"]])
. "<small>" . $language["TOPIC_PLEASE_REGISTER_NOTE"] . "</small>";
?></h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<form name="regForm" role="form" action="index.php" method="post"> <form name="regForm" role="form" action="index.php" method="post">
<?php if ($storeFirstLastName) { ?> <?php if ($storeFirstLastName) { ?>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<div class="form-group"> <div class="form-group">
<input type="text" name="first_name" id="first_name" class="form-control input-sm" <input type="text" name="first_name" id="first_name" class="form-control input-sm"
placeholder="<?php echo $language["FIRST_NAME"]; ?>" pattern="[A-Z][a-z]+"> placeholder="<?php echo $language["FIRST_NAME"]; ?>" pattern="[A-Z][a-z]+">
</div>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
<div class="form-group">
<input type="text" name="last_name" id="last_name" class="form-control input-sm"
placeholder="<?php echo $language["LAST_NAME"]; ?>" pattern="[A-Z][a-z]+">
</div>
</div> </div>
</div> </div>
<div class="col-xs-6 col-sm-6 col-md-6"> <?php } ?>
<div class="form-group">
<input type="text" name="last_name" id="last_name" class="form-control input-sm"
placeholder="<?php echo $language["LAST_NAME"]; ?>" pattern="[A-Z][a-z]+">
</div>
</div>
</div>
<?php } ?>
<div class="form-group"> <div class="form-group">
<input type="email" name="email" id="email" class="form-control input-sm" placeholder="<?php echo $language["EMAIL_ADDRESS"]; ?>" required> <input type="email" name="email" id="email" class="form-control input-sm" placeholder="<?php echo $language["EMAIL_ADDRESS"]; ?>" required>
@@ -180,7 +182,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<input type="text" name="username" id="username" class="form-control input-sm" <input type="text" name="username" id="username" class="form-control input-sm"
placeholder="<?php echo $language["USERNAME"]; ?>" pattern="[a-z1-9]{3,20}" required> placeholder="<?php echo $language["USERNAME"]; ?>" pattern="[a-z1-9]{3,20}" required>
</div> </div>
<?php if ($storePassword) { ?> <?php if ($storePassword) { ?>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<div class="form-group"> <div class="form-group">
@@ -193,16 +195,18 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
</div> </div>
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
<input type="hidden" name="token" id="token" value="<?php echo $_SESSION["token"]; ?>"> <input type="hidden" name="token" id="token" value="<?php echo $_SESSION["token"]; ?>">
<input type="submit" value="<?php echo $language["REGISTER"]; ?>" class="btn btn-info btn-block"> <input type="submit" value="<?php echo $language["REGISTER"]; ?>" class="btn btn-info btn-block">
</form> </form>
<?php if (isset($language["NOTE_FOR_REGISTRATION"])) { <?php
echo "<p>" . $language["NOTE"] . ": <br />"; if (isset($language["NOTE_FOR_REGISTRATION"])) {
echo strtr($language["NOTE_FOR_REGISTRATION"], [ "@homeserver" => $config["homeserver"] ]); echo "<p>" . $language["NOTE"] . ": <br />";
echo strtr($language["NOTE_FOR_REGISTRATION"], ["@homeserver" => $config["homeserver"]]);
echo "</p>"; echo "</p>";
} ?> }
?>
</div> </div>
</div> </div>
</div> </div>
@@ -246,4 +250,4 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
<?php } ?> <?php } ?>
</script> </script>
<?php } ?> <?php } ?>
</body></html> </body></html>

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once "../language.php"; require_once(__DIR__ . "/../language.php");
if (!file_exists("../config.php")) { if (!file_exists("../config.php")) {
print($language["NO_CONFIGURATION"]); print($language["NO_CONFIGURATION"]);
exit(); exit();
} }
require_once "../config.php"; require_once(__DIR__ . "/../config.php");
require_once "../mail_templates.php"; require_once(__DIR__ . "/../mail_templates.php");
// enforce admin via https // enforce admin via https
if (!isset($_SERVER['HTTPS'])) { if (!isset($_SERVER['HTTPS'])) {
@@ -38,7 +38,7 @@ try {
} }
$token = filter_var($_GET["t"], FILTER_SANITIZE_STRING); $token = filter_var($_GET["t"], FILTER_SANITIZE_STRING);
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
$user = $mx_db->getUserForVerify($token); $user = $mx_db->getUserForVerify($token);
if ($user == NULL) { if ($user == NULL) {
@@ -51,21 +51,21 @@ try {
$email = $user["email"]; $email = $user["email"];
$admin_token = $user["admin_token"]; $admin_token = $user["admin_token"];
require_once("../MatrixConnection.php"); require_once(__DIR__ . "/../MatrixConnection.php");
$adminUrl = $config["webroot"] . "/verify_admin.php?t=" . $admin_token; $adminUrl = $config["webroot"] . "/verify_admin.php?t=" . $admin_token;
$mxConn = new MatrixConnection($config["homeserver"], $config["access_token"]); $mxConn = new MatrixConnection($config["homeserver"], $config["access_token"]);
$mxMsg = new MatrixMessage(); $mxMsg = new MatrixMessage();
$mxMsg->set_body(strtr($language["MSG_USER_WANTS_REGISTER"], [ $mxMsg->set_body(strtr($language["MSG_USER_WANTS_REGISTER"], [
"@name" => (strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username), "@name" => (strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username),
"@note" => $note, "@note" => $note,
"@adminUrl" => $adminUrl "@adminUrl" => $adminUrl
])); ]));
if (isset($language["MSG_USER_WANTS_REGISTER_FORMATTED"])) { if (isset($language["MSG_USER_WANTS_REGISTER_FORMATTED"])) {
$mxMsg->set_formatted_body(strtr($language["MSG_USER_WANTS_REGISTER_FORMATTED"], [ $mxMsg->set_formatted_body(strtr($language["MSG_USER_WANTS_REGISTER_FORMATTED"], [
"@name" => (strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username), "@name" => (strlen($first_name . $last_name) > 0 ? $first_name . " " . $last_name : $username),
"@note" => $note, "@note" => $note,
"@adminUrl" => $adminUrl "@adminUrl" => $adminUrl
])); ]));
} }
$mxMsg->set_type("m.text"); $mxMsg->set_type("m.text");
$response = $mxConn->send($config["register_room"], $mxMsg); $response = $mxConn->send($config["register_room"], $mxMsg);

View File

@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
require_once "../language.php"; require_once(__DIR__ . "/../language.php");
if (!file_exists("../config.php")) { if (!file_exists("../config.php")) {
print($language["NO_CONFIGURATION"]); print($language["NO_CONFIGURATION"]);
exit(); exit();
} }
require_once "../config.php"; require_once(__DIR__ . "/../config.php");
require_once "../mail_templates.php"; require_once(__DIR__ . "/../mail_templates.php");
// enforce admin via https // enforce admin via https
if (!isset($_SERVER['HTTPS'])) { if (!isset($_SERVER['HTTPS'])) {
@@ -38,7 +38,7 @@ try {
} }
$token = filter_var($_GET["t"], FILTER_SANITIZE_STRING); $token = filter_var($_GET["t"], FILTER_SANITIZE_STRING);
require_once("../database.php"); require_once(__DIR__ . "/../database.php");
$action = NULL; $action = NULL;
if (isset($_GET["allow"])) { if (isset($_GET["allow"])) {
@@ -67,7 +67,7 @@ try {
$mx_db->setRegistrationStateAdmin(RegisterState::PendingRegistration, $token); $mx_db->setRegistrationStateAdmin(RegisterState::PendingRegistration, $token);
// register user // register user
require_once("../MatrixConnection.php"); require_once(__DIR__ . "/../MatrixConnection.php");
$mxConn = new MatrixConnection($config["homeserver"], $config["access_token"]); $mxConn = new MatrixConnection($config["homeserver"], $config["access_token"]);
$password = NULL; $password = NULL;
@@ -93,7 +93,7 @@ try {
// send registration_success // send registration_success
$res = send_mail_registration_success( $res = send_mail_registration_success(
$config["homeserver"], $first_name . " " . $last_name, $email, $username, $password, $config["howToURL"] $config["homeserver"], $first_name . " " . $last_name, $email, $username, $password, $config["howToURL"]
); );
if ($res) { if ($res) {
$mx_db->setRegistrationStateAdmin(RegisterState::AllDone, $token); $mx_db->setRegistrationStateAdmin(RegisterState::AllDone, $token);
} else { } else {
@@ -154,9 +154,10 @@ try {
</div> </div>
<div class="panel-body"> <div class="panel-body">
<form name="appForm" role="form" action="verify_admin.php" method="GET"> <form name="appForm" role="form" action="verify_admin.php" method="GET">
<?php if (isset($config["operationMode"]) && $config["operationMode"] === "local") { <?php
// this values will not be used when using the register operation type if (isset($config["operationMode"]) && $config["operationMode"] === "local") {
?> // this values will not be used when using the register operation type
?>
<div class="row"> <div class="row">
<div class="col-xs-6 col-sm-6 col-md-6"> <div class="col-xs-6 col-sm-6 col-md-6">
<div class="form-group"> <div class="form-group">
@@ -171,7 +172,7 @@ try {
</div> </div>
</div> </div>
</div> </div>
<?php } ?> <?php } ?>
<div class="form-group"> <div class="form-group">
<input type="text" id="note" class="form-control input-sm" value="<?php echo $note; ?>" disabled=true> <input type="text" id="note" class="form-control input-sm" value="<?php echo $note; ?>" disabled=true>
</div> </div>
@@ -205,5 +206,5 @@ try {
print("<a href=\"" . $config["webroot"] . "/index.php" . "\">" . $language["JUMP_TO_HOMEPAGE"] . "</a>"); print("<a href=\"" . $config["webroot"] . "/index.php" . "\">" . $language["JUMP_TO_HOMEPAGE"] . "</a>");
} }
?> ?>
< /body> </body>
</html> </html>