From 2d7efd8d6c3ee03847ebb13357424289590d8041 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 8 Nov 2023 13:08:49 +0100 Subject: mod/notification-matrix: introduce $SetupMatrix{Authenticate,JoinRoom} for setup Well, now that we have a JSON parser... Let's improve the user experience a bit. --- doc/mod/notification-matrix.d/01-authenticate.avif | Bin 0 -> 4209 bytes doc/mod/notification-matrix.d/01-home-server.avif | Bin 2317 -> 0 bytes doc/mod/notification-matrix.d/02-access-token.avif | Bin 4105 -> 0 bytes doc/mod/notification-matrix.d/02-join-room.avif | Bin 0 -> 3955 bytes doc/mod/notification-matrix.d/03-join-room.avif | Bin 3166 -> 0 bytes doc/mod/notification-matrix.md | 73 +++++++++---------- global-functions.rsc | 2 +- mod/notification-matrix.rsc | 79 +++++++++++++++++++++ news-and-changes.rsc | 1 + 9 files changed, 115 insertions(+), 40 deletions(-) create mode 100644 doc/mod/notification-matrix.d/01-authenticate.avif delete mode 100644 doc/mod/notification-matrix.d/01-home-server.avif delete mode 100644 doc/mod/notification-matrix.d/02-access-token.avif create mode 100644 doc/mod/notification-matrix.d/02-join-room.avif delete mode 100644 doc/mod/notification-matrix.d/03-join-room.avif diff --git a/doc/mod/notification-matrix.d/01-authenticate.avif b/doc/mod/notification-matrix.d/01-authenticate.avif new file mode 100644 index 0000000..1db516b Binary files /dev/null and b/doc/mod/notification-matrix.d/01-authenticate.avif differ diff --git a/doc/mod/notification-matrix.d/01-home-server.avif b/doc/mod/notification-matrix.d/01-home-server.avif deleted file mode 100644 index 683c7b5..0000000 Binary files a/doc/mod/notification-matrix.d/01-home-server.avif and /dev/null differ diff --git a/doc/mod/notification-matrix.d/02-access-token.avif b/doc/mod/notification-matrix.d/02-access-token.avif deleted file mode 100644 index 54109a6..0000000 Binary files a/doc/mod/notification-matrix.d/02-access-token.avif and /dev/null differ diff --git a/doc/mod/notification-matrix.d/02-join-room.avif b/doc/mod/notification-matrix.d/02-join-room.avif new file mode 100644 index 0000000..edd6c81 Binary files /dev/null and b/doc/mod/notification-matrix.d/02-join-room.avif differ diff --git a/doc/mod/notification-matrix.d/03-join-room.avif b/doc/mod/notification-matrix.d/03-join-room.avif deleted file mode 100644 index 45974b8..0000000 Binary files a/doc/mod/notification-matrix.d/03-join-room.avif and /dev/null differ diff --git a/doc/mod/notification-matrix.md b/doc/mod/notification-matrix.md index 4ae6e18..b309d3d 100644 --- a/doc/mod/notification-matrix.md +++ b/doc/mod/notification-matrix.md @@ -21,8 +21,8 @@ Just install the module: $ScriptInstallUpdate mod/notification-matrix; Also install a Matrix client on at least one of your mobile and/or desktop -devices. As there is no privilege separation you should create a dedicated -notification account, in addition to your general user account. +devices. Create and setup an account there, we will reference that as +"*general account*" later. Configuration ------------- @@ -35,58 +35,53 @@ reload the configuration. > [`global-config`](../../global-config.rsc) (the one without `-overlay`) to > your local `global-config-overlay` and modify it to your specific needs. -### Home server +The Matrix server is connected via encrypted https, and certificate +verification is applied. So make sure you have the certificate chain for +your server in device's certificate store. -Matrix user accounts are identified by a unique user id in the form of -`@localpart:domain`. The `domain` part is not necessarily your home server -address, you have to resolve it with the procedure described in the -[Matrix specification](https://spec.matrix.org/latest/client-server-api/#server-discovery). - -Your best bet is to query the server at `domain` with the -[well-known uri](https://spec.matrix.org/latest/client-server-api/#well-known-uri). -For "*matrix.org*" this query is: +> ℹ️ **Info**: The *matrix.org* server uses a Cloudflare certificate. You can +> install that with: `$CertificateAvailable "Cloudflare Inc ECC CA-3"` - /tool/fetch "https://matrix.org/.well-known/matrix/client" output=user; +### From other device -![home server](notification-matrix.d/01-home-server.avif) +If you have setup your Matrix *notification account* before just reuse that. +Copy the relevant configuration to the device to be configured. -So the home server for "*matrix.org*" is "*matrix-client.matrix.org*". -Please strip the protocol ("*https://*") for `MatrixHomeServer` if given. +### Setup new account -### Access token +As there is no privilege separation you should create a dedicated account +for use with these scripts, in addition to your *general account*. +We will reference that as "*notification account*" in the following steps. -After discovering the correct home server an access token has to be created. -For this the login credentials (username and password) of the notification -account must be sent to the home server via -[client server api](https://matrix.org/docs/guides/client-server-api#login). +#### Authenticate -We use the home server discovered above, "*matrix-client.matrix.org*". -The user is "*example*" and password is "*v3ry-s3cr3t*". +Matrix user accounts are identified by a unique user id in the form of +`@localpart:domain`. Use that and your password to generate an access token +and write first part of the configuration: - /tool/fetch "https://matrix-client.matrix.org/_matrix/client/r0/login" http-method=post http-data="{\"type\":\"m.login.password\", \"user\":\"example\", \"password\":\"v3ry-s3cr3t\"}" output=user; + $SetupMatrixAuthenticate "@example:matrix.org" "v3ry-s3cr3t"; -![access token](notification-matrix.d/02-access-token.avif) +![authenticate](notification-matrix.d/01-authenticate.avif) -The server replied with a JSON object containing the `access_token`, use that -for `MatrixAccessToken`. +#### Join Room -### Room +Every Matix chat is a room, so we have to create one. Do that with your +*general account*, this makes sure your *general account* is the room owner. +Then join the room and invite the *notification account* by its user id +"*@example:matrix.org*". +Look up the *room id* within the Matrix client, it should read like +"*!WUcxpSjKyxSGelouhA:matrix.org*" (starting with an exclamation mark and +ending with the domain). -Every Matix chat is a room, so we have to create one. Do so with your general -user, this makes sure your general user is the room owner. Then join the room -and invite the notification user by its user id "*@example:matrix.org*". Look -up the room id within the Matrix client, it should read like -"*!WUcxpSjKyxSGelouhA:matrix.org*". Use that for `MatrixRoom`. +Finally make the *notification account* join into the room by accepting +the invite. -Finally join the notification user to the room by accepting the invite. Again, -this can be done with -[client server api](https://matrix.org/docs/guides/client-server-api#joining-a-room-via-an-invite). -Make sure to replace room id ("*!*" is escaped with "*%21*") and access token -with your data. + $SetupMatrixJoinRoom "!WUcxpSjKyxSGelouhA:matrix.org"; - /tool/fetch "https://matrix-client.matrix.org/_matrix/client/r0/rooms/%21WUcxpSjKyxSGelouhA:matrix.org/join?access_token=yt_ZXdvcm0tdGVzdA_NNqUyvKHRhBLZmnzVVSK_0xu6yN" http-method=post http-data="" output=user; +![join room](notification-matrix.d/02-join-room.avif) -![join room](notification-matrix.d/03-join-room.avif) +The settings have been appended to `global-config-overlay`. You may want to +edit to move it to an appropriate place. Usage and invocation -------------------- diff --git a/global-functions.rsc b/global-functions.rsc index 7eb1ec5..5c6e3c5 100644 --- a/global-functions.rsc +++ b/global-functions.rsc @@ -12,7 +12,7 @@ :local 0 "global-functions"; # expected configuration version -:global ExpectedConfigVersion 112; +:global ExpectedConfigVersion 113; # global variables not to be changed by user :global GlobalFunctionsReady false; diff --git a/mod/notification-matrix.rsc b/mod/notification-matrix.rsc index 03cfb13..a8983a7 100644 --- a/mod/notification-matrix.rsc +++ b/mod/notification-matrix.rsc @@ -12,6 +12,8 @@ :global PurgeMatrixQueue; :global SendMatrix; :global SendMatrix2; +:global SetupMatrixAuthenticate; +:global SetupMatrixJoinRoom; # flush Matrix queue :set FlushMatrixQueue do={ @@ -175,3 +177,80 @@ ($NotificationFunctions->"matrix") ("\$NotificationFunctions->\"matrix\"") $Notification; } + +# setup - get home server and access token +:set SetupMatrixAuthenticate do={ + :local User [ :tostr $1 ]; + :local Pass [ :tostr $2 ]; + + :global CharacterReplace; + :global LogPrintExit2; + :global ParseJson; + :global UrlEncode; + + :global MatrixAccessToken; + :global MatrixHomeServer; + + :local Domain [ :pick $User ([ :find $User ":" ] + 1) [ :len $User] ]; + :do { + :local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ + ("https://" . $Domain . "/.well-known/matrix/client") as-value ]->"data"); + :set MatrixHomeServer ([ $ParseJson ([ $ParseJson [ $CharacterReplace $Data " " "" ] ]->"m.homeserver") ]->"base_url"); + $LogPrintExit2 debug $0 ("Home server is: " . $MatrixHomeServer) false; + } on-error={ + $LogPrintExit2 error $0 ("Failed getting home server!") true; + } + + :if ([ :pick $MatrixHomeServer 0 8 ] = "https://") do={ + :set MatrixHomeServer [ :pick $MatrixHomeServer 8 [ :len $MatrixHomeServer ] ]; + } + + :do { + :local Data ([ /tool/fetch check-certificate=yes-without-crl output=user \ + http-method=post http-data=("{\"type\":\"m.login.password\", \"user\":\"" . $User . "\", \"password\":\"" . $Pass . "\"}") \ + ("https://" . $MatrixHomeServer . "/_matrix/client/r0/login") as-value ]->"data"); + :set MatrixAccessToken ([ $ParseJson $Data ]->"access_token"); + $LogPrintExit2 debug $0 ("Access token is: " . $MatrixAccessToken) false; + } on-error={ + $LogPrintExit2 error $0 ("Failed logging in (and getting access token)!") true; + } + + :do { + /system/script/set global-config-overlay source=([ get global-config-overlay source ] . "\n" . \ + ":global MatrixHomeServer \"" . $MatrixHomeServer . "\";\n" . \ + ":global MatrixAccessToken \"" . $MatrixAccessToken . "\";\n"); + $LogPrintExit2 info $0 ("Appended configuration to global-config-overlay. Now create and join a room, please!") false; + } on-error={ + $LogPrintExit2 error $0 ("Failed appending configuration to global-config-overlay!") true; + } +} + +# setup - join a room +:set SetupMatrixJoinRoom do={ + :global MatrixRoom [ :tostr $1 ]; + + :global LogPrintExit2; + :global UrlEncode; + + :global MatrixAccessToken; + :global MatrixHomeServer; + :global MatrixRoom; + + :do { + /tool/fetch check-certificate=yes-without-crl output=none \ + http-method=post http-data="" \ + ("https://" . $MatrixHomeServer . "/_matrix/client/r0/rooms/" . [ $UrlEncode $MatrixRoom ] . \ + "/join?access_token=" . [ $UrlEncode $MatrixAccessToken ]) as-value; + $LogPrintExit2 debug $0 ("Joined the room.") false; + } on-error={ + $LogPrintExit2 error $0 ("Failed joining the room!") true; + } + + :do { + /system/script/set global-config-overlay source=([ get global-config-overlay source ] . "\n" . \ + ":global MatrixRoom \"" . $MatrixRoom . "\";\n"); + $LogPrintExit2 info $0 ("Appended configuration to global-config-overlay. Please review and cleanup!") false; + } on-error={ + $LogPrintExit2 error $0 ("Failed appending configuration to global-config-overlay!") true; + } +} diff --git a/news-and-changes.rsc b/news-and-changes.rsc index babcec8..64e114f 100644 --- a/news-and-changes.rsc +++ b/news-and-changes.rsc @@ -26,6 +26,7 @@ 110="Dropped support for loading scripts from local storage."; 111="Modified 'dhcp-to-dns' to allow multiple records for one mac address."; 112="Enhanced 'mod/ssh-keys-import' to record the fingerprint of keys."; + 113="Added helper functions for easier setup to Matrix notification module."; }; # Migration steps to be applied on script updates -- cgit v1.2.3-70-g09d2