-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into hs/update-dependencies
- Loading branch information
Showing
19 changed files
with
279 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Support for E2E Encrypted rooms is now considered stable and can be enabled in production. Please see the [documentation](https://matrix-org.github.io/matrix-hookshot/latest/advanced/encryption.html) | ||
on the requirements for enabling support. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,37 @@ | ||
Encryption | ||
========== | ||
|
||
<section class="warning"> | ||
Encryption support is <strong>HIGHLY EXPERIMENTAL AND SUBJECT TO CHANGE</strong>. It should not be enabled for production workloads. | ||
For more details, see <a href="https://github.com/matrix-org/matrix-hookshot/issues/594">issue 594</a>. | ||
<section class="notice"> | ||
Support for encryption is considered stable, but the underlying specification changes are not yet. | ||
|
||
Hookshot supports end-to-bridge encryption via [MSC3202](https://github.com/matrix-org/matrix-spec-proposals/pull/3202), and [MSC4203](https://github.com/matrix-org/matrix-spec-proposals/pull/4203). Hookshot needs to be configured against a a homeserver that supports these features, such as [Synapse](#running-with-synapse). | ||
|
||
Please check with your homeserver implementation before reporting bugs against matrix-hookshot. | ||
</section> | ||
|
||
Hookshot supports end-to-bridge encryption via [MSC3202](https://github.com/matrix-org/matrix-spec-proposals/pull/3202). As such, encryption requires Hookshot to be connected to a homeserver that supports that MSC, such as [Synapse](#running-with-synapse). | ||
|
||
|
||
## Enabling encryption in Hookshot | ||
|
||
In order for Hookshot to use encryption, it must be configured as follows: | ||
- The `experimentalEncryption.storagePath` setting must point to a directory that Hookshot has permissions to write files into. If running with Docker, this path should be within a volume (for persistency). Hookshot uses this directory for its crypto store (i.e. long-lived state relating to its encryption keys). | ||
- The `encryption.storagePath` setting must point to a directory that Hookshot has permissions to write files into. If running with Docker, this path should be within a volume (for persistency). Hookshot uses this directory for its crypto store (i.e. long-lived state relating to its encryption keys). | ||
- Once a crypto store has been initialized, its files must not be modified, and Hookshot cannot be configured to use another crypto store of the same type as one it has used before. If a crypto store's files get lost or corrupted, Hookshot may fail to start up, or may be unable to decrypt command messages. To fix such issues, stop Hookshot, then reset its crypto store by running `yarn start:resetcrypto`. | ||
- [Redis](./workers.md) must be enabled. Note that worker mode is not yet supported with encryption, so `queue` MUST **NOT be configured**. | ||
|
||
If you ever reset your homeserver's state, ensure you also reset Hookshot's encryption state. This includes clearing the `experimentalEncryption.storagePath` directory and all worker state stored in your redis instance. Otherwise, Hookshot may fail on start up with registration errors. | ||
If you ever reset your homeserver's state, ensure you also reset Hookshot's encryption state. This includes clearing the `storagePath` directory and all worker state stored in your redis instance. Otherwise, Hookshot may fail on start up with registration errors. | ||
|
||
Also ensure that Hookshot's appservice registration file contains every line from `registration.sample.yml` that appears after the `If enabling encryption` comment. Note that changing the registration file may require restarting the homeserver that Hookshot is connected to. | ||
|
||
## Running with Synapse | ||
|
||
[Synapse](https://github.com/matrix-org/synapse/) has functional support for MSC3202 as of [v1.63.0](https://github.com/matrix-org/synapse/releases/tag/v1.63.0). To enable it, add the following section to Synapse's configuration file (typically named `homeserver.yaml`): | ||
[Synapse](https://github.com/matrix-org/synapse/) has functional support for MSC3202 and MSC4203 as of [v1.63.0](https://github.com/matrix-org/synapse/releases/tag/v1.63.0). To enable it, add the following section to Synapse's configuration file (typically named `homeserver.yaml`): | ||
|
||
You may notice that MSC2409 is not listed above. Due to the changes being split out from MSC2409, `msc2409_to_device_messages_enabled` refers to MSC4203. | ||
|
||
```yaml | ||
experimental_features: | ||
msc3202_device_masquerading: true | ||
msc3202_transaction_extensions: true | ||
msc2409_to_device_messages_enabled: true | ||
``` | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { MessageEventContent } from "matrix-bot-sdk"; | ||
import { E2ESetupTestTimeout, E2ETestEnv } from "./util/e2e-test"; | ||
import { describe, it, beforeEach, afterEach } from "@jest/globals"; | ||
|
||
const CryptoRoomState = [{ | ||
content: { | ||
"algorithm": "m.megolm.v1.aes-sha2" | ||
}, | ||
state_key: "", | ||
type: "m.room.encryption" | ||
}]; | ||
|
||
describe('End-2-End Encryption support', () => { | ||
let testEnv: E2ETestEnv; | ||
|
||
beforeEach(async () => { | ||
testEnv = await E2ETestEnv.createTestEnv({ matrixLocalparts: ['user'], enableE2EE: true }); | ||
await testEnv.setUp(); | ||
}, E2ESetupTestTimeout); | ||
|
||
afterEach(() => { | ||
return testEnv?.tearDown(); | ||
}); | ||
|
||
it('should be able to send the help command', async () => { | ||
const user = testEnv.getUser('user'); | ||
const testRoomId = await user.createRoom({ name: 'Test room', invite:[testEnv.botMxid], initial_state: CryptoRoomState}); | ||
await user.setUserPowerLevel(testEnv.botMxid, testRoomId, 50); | ||
await user.waitForRoomJoin({sender: testEnv.botMxid, roomId: testRoomId }); | ||
await user.sendText(testRoomId, "!hookshot help"); | ||
await user.waitForRoomEvent<MessageEventContent>({ | ||
eventType: 'm.room.message', sender: testEnv.botMxid, roomId: testRoomId, | ||
}); | ||
}); | ||
it('should send notices in an encrypted format', async () => { | ||
const user = testEnv.getUser('user'); | ||
const testRoomId = await user.createRoom({ name: 'Test room', invite:[testEnv.botMxid], initial_state: CryptoRoomState}); | ||
await user.setUserPowerLevel(testEnv.botMxid, testRoomId, 50); | ||
await user.waitForRoomJoin({sender: testEnv.botMxid, roomId: testRoomId }); | ||
await user.sendText(testRoomId, "!hookshot webhook test-webhook"); | ||
const inviteResponse = await user.waitForRoomInvite({sender: testEnv.botMxid}); | ||
await user.waitForEncryptedEvent<MessageEventContent>({ | ||
eventType: 'm.room.message', sender: testEnv.botMxid, roomId: testRoomId, | ||
body: 'Room configured to bridge webhooks. See admin room for secret url.' | ||
}); | ||
const webhookUrlMessage = user.waitForEncryptedEvent<MessageEventContent>({ | ||
eventType: 'm.room.message', sender: testEnv.botMxid, roomId: inviteResponse.roomId | ||
}); | ||
await user.joinRoom(inviteResponse.roomId); | ||
const msgData = (await webhookUrlMessage).data.content.body; | ||
const webhookUrl = msgData.split('\n')[2]; | ||
const webhookNotice = user.waitForEncryptedEvent<MessageEventContent>({ | ||
eventType: 'm.room.message', sender: testEnv.botMxid, roomId: testRoomId, body: 'Hello world!' | ||
}); | ||
|
||
// Send a webhook | ||
await fetch(webhookUrl, { | ||
method: 'POST', | ||
headers: { 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({text: 'Hello world!'}) | ||
}); | ||
|
||
// And await the notice. | ||
await webhookNotice; | ||
}); | ||
}); |
Oops, something went wrong.