mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-07-07 22:31:36 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ee75232454 | |||
| 9962946082 | |||
| 4454e54092 | |||
| f148975260 | |||
| 431ff348c3 | |||
| ad4f7973cb | |||
| 431fb7330e | |||
| 6619e6a20a | |||
| f205e2f890 | |||
| e9e0db8bab |
@@ -57,3 +57,15 @@ repos:
|
||||
types: [rust]
|
||||
stages:
|
||||
- pre-push
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: docs-build
|
||||
name: docs build
|
||||
entry: npm run docs:build
|
||||
language: system
|
||||
pass_filenames: false
|
||||
files: docs/
|
||||
types: [mdx]
|
||||
stages:
|
||||
- pre-commit
|
||||
|
||||
Generated
+22
-21
@@ -4600,8 +4600,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma"
|
||||
version = "0.15.1"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.16.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"js_int",
|
||||
@@ -4619,8 +4619,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-appservice-api"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.16.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -4631,8 +4631,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-client-api"
|
||||
version = "0.23.1"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.24.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"assign",
|
||||
@@ -4653,8 +4653,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-common"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"base64 0.22.1",
|
||||
@@ -4686,8 +4686,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-events"
|
||||
version = "0.33.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.34.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"indexmap 2.14.0",
|
||||
@@ -4707,8 +4707,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-federation-api"
|
||||
version = "0.14.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"headers",
|
||||
@@ -4731,7 +4731,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-identifiers-validation"
|
||||
version = "0.12.1"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"thiserror 2.0.18",
|
||||
@@ -4739,8 +4739,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-macros"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.19.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"cfg-if",
|
||||
@@ -4755,8 +4755,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-push-gateway-api"
|
||||
version = "0.14.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -4767,8 +4767,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-signatures"
|
||||
version = "0.20.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"ed25519-dalek",
|
||||
@@ -4776,6 +4776,7 @@ dependencies = [
|
||||
"pkcs8",
|
||||
"rand 0.10.2",
|
||||
"ruma-common",
|
||||
"ruma-events",
|
||||
"serde_json",
|
||||
"sha2 0.10.9",
|
||||
"thiserror 2.0.18",
|
||||
@@ -4783,8 +4784,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-state-res"
|
||||
version = "0.16.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=3ecd80b92794d2d93f657a7b3db62d4be237526b#3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
version = "0.17.0"
|
||||
source = "git+https://github.com/ruma/ruma.git?rev=89cce34f3d498525769973243122914910c00ce5#89cce34f3d498525769973243122914910c00ce5"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
|
||||
+1
-1
@@ -350,7 +350,7 @@ version = "1.1.1"
|
||||
[workspace.dependencies.ruma]
|
||||
# version = "0.14.1"
|
||||
git = "https://github.com/ruma/ruma.git"
|
||||
rev = "3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
rev = "89cce34f3d498525769973243122914910c00ce5"
|
||||
features = [
|
||||
"appservice-api-c",
|
||||
"client-api",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Removed the `/_conduwuit/` versions of the `local_user_count` and `version` routes. These routes are still accessible under the `/_continuwuity` prefix.
|
||||
+2
-2
@@ -36,8 +36,8 @@
|
||||
},
|
||||
{
|
||||
"type": "dir",
|
||||
"name": "guides",
|
||||
"label": "Guides"
|
||||
"name": "advanced",
|
||||
"label": "Advanced"
|
||||
},
|
||||
"security",
|
||||
{
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
[
|
||||
{
|
||||
"text": "Documentation",
|
||||
"text": "Guide",
|
||||
"link": "/introduction",
|
||||
"activeMatch": "^/(introduction|configuration|deploying|calls|appservices|maintenance|troubleshooting|guides)"
|
||||
"activeMatch": "^/(introduction|configuration|deploying|calls|appservices|maintenance|troubleshooting|advanced)"
|
||||
},
|
||||
{
|
||||
"text": "Development",
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
"type": "file",
|
||||
"name": "performance",
|
||||
"label": "Performance tuning"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "oidc",
|
||||
"label": "Delegated authentication"
|
||||
}
|
||||
|
||||
]
|
||||
@@ -58,13 +58,6 @@ # Defaults to members of the admin room if unset
|
||||
|
||||
To enable full discovery, you will need to reverse proxy these paths from the base domain back to Continuwuity.
|
||||
|
||||
:::warning
|
||||
If you choose to serve the well-known files directly through your reverse proxy, and you are
|
||||
using delegation, you must still set the `global.well_known.client` configuration option to
|
||||
the domain you're delegating to. Continuwuity needs to know the domain it runs on for OAuth-compatible
|
||||
clients to work correctly.
|
||||
:::
|
||||
|
||||
## Reverse proxying well-known files to Continuwuity
|
||||
|
||||
<details>
|
||||
@@ -44,7 +44,7 @@ ### Prerequisites
|
||||
- Alternatively, if you want both client and federation traffic on `:443`, you can configure `CONTINUWUITY_WELL_KNOWN` following some of the [examples](#choose-your-reverse-proxy) below.
|
||||
|
||||
:::tip Split-domain setups
|
||||
For more setups with `.well-known` delegation and split-domain deployments, consult the [Delegation/Split-domain](../guides/delegation) page.
|
||||
For more setups with `.well-known` delegation and split-domain deployments, consult the [Delegation/Split-domain](../advanced/delegation) page.
|
||||
:::
|
||||
|
||||
## Docker Compose
|
||||
@@ -79,7 +79,7 @@ ### Choose Your Reverse Proxy
|
||||
nameserver 1.1.1.1
|
||||
```
|
||||
|
||||
Consult the [**DNS tuning guide (recommended)**](../guides/dns.mdx) for full solutions to this issue.
|
||||
Consult the [**DNS tuning guide (recommended)**](../advanced/dns.mdx) for full solutions to this issue.
|
||||
:::
|
||||
|
||||
#### Caddy (using Caddyfile)
|
||||
@@ -269,7 +269,7 @@ ### Accessing the Server's Console
|
||||
|
||||
## Next steps
|
||||
|
||||
- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../guides/dns.mdx) (recommended)
|
||||
- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../advanced/dns.mdx) (recommended)
|
||||
- To set up Audio/Video communication, see the [**Calls**](../calls.mdx) page.
|
||||
- Consult the [Maintenance](../maintenance.mdx) page for guidance on maintaining your homeserver.
|
||||
- If you want to set up an appservice, take a look at the [**Appservice Guide**](../appservices.mdx).
|
||||
|
||||
@@ -170,7 +170,7 @@ ## Exposing ports in the firewall or the router
|
||||
are: `ufw allow 8448/tcp` and `ufw allow 443/tcp`.
|
||||
|
||||
:::tip Alternative port/domain setups
|
||||
If you would like to use only port 443, a different port, or a subdomain for the homeserver, you will need to set up `.well-known` delegation. Consult the `[global.well_known]` section of the config file, and the [**Delegation/Split-domain**](../guides/delegation) page to learn more about these kinds of deployments.
|
||||
If you would like to use only port 443, a different port, or a subdomain for the homeserver, you will need to set up `.well-known` delegation. Consult the `[global.well_known]` section of the config file, and the [**Delegation/Split-domain**](../advanced/delegation) page to learn more about these kinds of deployments.
|
||||
:::
|
||||
|
||||
## Setting up the Reverse Proxy
|
||||
@@ -207,7 +207,7 @@ ### Other Reverse Proxies
|
||||
|
||||
- `/_matrix/client` - core Client-Server APIs. These should be available on port :443
|
||||
|
||||
- `/_conduwuit/` and `/_continuwuity/` - ad-hoc Continuwuity routes for password resets, email verification, and server details such as `/local_user_count` and `/server_version`.
|
||||
- `/_continuwuity/` - Continuwuity's integrated account management interface for OAuth-compatible clients
|
||||
|
||||
You can optionally reverse proxy the following individual routes:
|
||||
|
||||
@@ -300,8 +300,7 @@ # For client-server endpoints
|
||||
|
||||
## What's next?
|
||||
|
||||
- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../guides/dns.mdx) (recommended)
|
||||
- To configure OIDC login with an identity provider, see the [**delegated authentication guide**](../guides/oidc.mdx).
|
||||
- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../advanced/dns.mdx) (recommended)
|
||||
- For Audio/Video call functionality see the [**Calls**](../calls.md) page.
|
||||
- Consult the [Maintenance](../maintenance.mdx) page for guidance on maintaining your homeserver.
|
||||
- If you want to set up an appservice, take a look at the [**Appservice Guide**](../appservices.md).
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# Configuring delegated authentication
|
||||
|
||||
Continuwuity supports delegating user authentication to an external identity provider that implements the OpenID Connect specification, such as Authentik, kanidm, or Keycloak.
|
||||
|
||||
:::warning{title="OIDC versus OAuth, and supported clients"}
|
||||
**OIDC** is not to be confused with **OAuth**. In the context of Matrix, OAuth is the protocol that Matrix clients use to authenticate with the _homeserver_. OIDC is the protocol that the _homeserver_ uses to communicate with the _identity provider_. Continuwuity supports OAuth by default, alongside the legacy **UIAA** authentication framework.
|
||||
|
||||
When OIDC is configured, Continuwuity will disable its support for legacy authentication. **Only clients that support OAuth**, such as the Element family of clients, will be able to log in when OIDC is configured. If your client of choice shows an error when you try to log in after configuring OIDC, it likely does not support OAuth. This is an issue with your client, not Continuwuity, and should be reported to your client's developers.
|
||||
:::
|
||||
|
||||
A simple OIDC configuration is as easy as creating a new OIDC application in your identity provider's settings and supplying Continuwuity with the client ID and client secret. This guide will use kanidm as an example, but the described steps are broadly applicable to other identity providers.
|
||||
|
||||
First, create a new application for Continuwuity in your identity provider.
|
||||
```sh
|
||||
# Here, `c10y` is the client ID that kanidm will use, and `Continuwuity` is the display name.
|
||||
# Other identity providers may generate a client ID for you.
|
||||
# Use the domain that clients can reach Continuwuity at, which may not be the same as your server name
|
||||
# if you have configured well-known delegation.
|
||||
kanidm system oauth2 create c10y Continuwuity https://matrix.yourdomain.com
|
||||
```
|
||||
|
||||
Configure the redirect URL that Continuwuity uses.
|
||||
```sh
|
||||
kanidm system oauth2 add-redirect-url c10y https://matrix.yourdomain.com/_continuwuity/oidc/complete
|
||||
```
|
||||
|
||||
Allow Continuwuity to request the `openid` scope. Other identity providers may not require this step.
|
||||
```sh
|
||||
kanidm system oauth2 update-scope-map c10y idm_all_persons openid
|
||||
```
|
||||
|
||||
Find the client secret that was generated. Other identity providers may show this information in their web UI.
|
||||
```sh
|
||||
kanidm system oauth2 show-basic-secret c10y
|
||||
d1qgx352kkuvs1j70b6w293d65x68jve1f7b27fyk90gjhpr
|
||||
```
|
||||
|
||||
Configure Continuwuity with the client ID, client secret, and discovery URL. kanidm has a different discovery URL for each client, but other identity providers may have a single discovery URL at the root of their domain.
|
||||
|
||||
```toml
|
||||
[global.oauth.oidc]
|
||||
|
||||
# `/.well-known/openid-configuration` will be appended automatically
|
||||
discovery_url = "https://idm.example.com/oauth2/openid/c10y"
|
||||
|
||||
# This may be randomly generated by your identity provider. kanidm requires
|
||||
# you to set it manually when you create the application.
|
||||
client_id = "c10y"
|
||||
|
||||
# From the previous step
|
||||
client_secret = "d1qgx352kkuvs1j70b6w293d65x68jve1f7b27fyk90gjhpr"
|
||||
```
|
||||
|
||||
Finally, restart Continuwuity, and log out and back in again. Your client should prompt you to continue in your web browser and open a webpage with the Continuwuity logo that allows you to continue in your identity provider. Once you log in successfully, you will be prompted to choose a user ID -- to link your existing account, enter its user ID, and then your old password when prompted.
|
||||
|
||||
Continuwuity offers several additional configuration options to tweak its integration with your identity provider. Review the `[global.oauth.oidc]` section towards the bottom of the [reference configuration](../reference/config) for a complete list of options and documentation.
|
||||
@@ -60,7 +60,7 @@ ### DNS server overload
|
||||
|
||||
Matrix federation is extremely heavy and sends wild amounts of DNS requests. This makes normal resolvers like the ones above unsuitable for its activity. Ultimately, the best solution/fix for this is to selfhost a high quality caching DNS resolver such as Unbound, and configure Continuwuity to use it.
|
||||
|
||||
Follow the [**DNS tuning guide**](./guides/dns) for details on setting it up.
|
||||
Follow the [**DNS tuning guide**](./advanced/dns) for details on setting it up.
|
||||
|
||||
### Intermittent federation failures to a specific server
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ pub(super) async fn list_users(&self) -> Result {
|
||||
let users: Vec<_> = self
|
||||
.services
|
||||
.users
|
||||
.list_local_users()
|
||||
.stream_local_users()
|
||||
.map(|id| id.as_str().to_owned())
|
||||
.collect()
|
||||
.await;
|
||||
@@ -588,7 +588,7 @@ pub(super) async fn force_join_all_local_users(
|
||||
for user_id in &self
|
||||
.services
|
||||
.users
|
||||
.list_local_users()
|
||||
.stream_local_users()
|
||||
.collect::<Vec<_>>()
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -29,26 +29,26 @@ pub(crate) async fn get_supported_versions_route(
|
||||
))
|
||||
}
|
||||
|
||||
/// # `GET /_conduwuit/server_version`
|
||||
/// # `GET /_continuwuity/server_version`
|
||||
///
|
||||
/// Conduwuit-specific API to get the server version, results akin to
|
||||
/// `/_matrix/federation/v1/version`
|
||||
pub(crate) async fn conduwuit_server_version() -> Result<impl IntoResponse> {
|
||||
pub(crate) async fn continuwuity_server_version() -> Result<impl IntoResponse> {
|
||||
Ok(Json(serde_json::json!({
|
||||
"name": conduwuit::BRANDING,
|
||||
"version": conduwuit::version(),
|
||||
})))
|
||||
}
|
||||
|
||||
/// # `GET /_conduwuit/local_user_count`
|
||||
/// # `GET /_continuwuity/local_user_count`
|
||||
///
|
||||
/// conduwuit-specific API to return the amount of users registered on this
|
||||
/// homeserver. Endpoint is disabled if federation is disabled for privacy. This
|
||||
/// only includes active users (not deactivated, etc)
|
||||
pub(crate) async fn conduwuit_local_user_count(
|
||||
pub(crate) async fn continuwuity_local_user_count(
|
||||
State(services): State<crate::State>,
|
||||
) -> Result<impl IntoResponse> {
|
||||
let user_count = services.users.list_local_users().count().await;
|
||||
let user_count = services.users.stream_local_users().count().await;
|
||||
|
||||
Ok(Json(serde_json::json!({
|
||||
"count": user_count
|
||||
|
||||
+2
-5
@@ -190,8 +190,7 @@ pub fn build(router: Router<State>, state: State) -> Router<State> {
|
||||
.ruma_route(&client::room_initial_sync_route)
|
||||
.ruma_route(&client::get_authorization_server_metadata_route)
|
||||
.merge(client::oauth::router(state))
|
||||
.route("/_conduwuit/server_version", get(client::conduwuit_server_version))
|
||||
.route("/_continuwuity/server_version", get(client::conduwuit_server_version))
|
||||
.route("/_continuwuity/server_version", get(client::continuwuity_server_version))
|
||||
.ruma_route(&admin::rooms::ban::ban_room)
|
||||
.ruma_route(&admin::rooms::list::list_rooms);
|
||||
|
||||
@@ -229,14 +228,12 @@ pub fn build(router: Router<State>, state: State) -> Router<State> {
|
||||
.ruma_route(&server::well_known_server)
|
||||
.ruma_route(&server::get_content_route)
|
||||
.ruma_route(&server::get_content_thumbnail_route)
|
||||
.route("/_conduwuit/local_user_count", get(client::conduwuit_local_user_count))
|
||||
.route("/_continuwuity/local_user_count", get(client::conduwuit_local_user_count));
|
||||
.route("/_continuwuity/local_user_count", get(client::continuwuity_local_user_count));
|
||||
} else {
|
||||
router = router
|
||||
.route("/_matrix/federation/{*path}", any(federation_disabled))
|
||||
.route("/.well-known/matrix/server", any(federation_disabled))
|
||||
.route("/_matrix/key/{*path}", any(federation_disabled))
|
||||
.route("/_conduwuit/local_user_count", any(federation_disabled))
|
||||
.route("/_continuwuity/local_user_count", any(federation_disabled));
|
||||
}
|
||||
|
||||
|
||||
@@ -119,8 +119,6 @@ pub enum Error {
|
||||
Mxc(#[from] ruma::MxcUriError),
|
||||
#[error(transparent)]
|
||||
Mxid(#[from] ruma::IdParseError),
|
||||
#[error("from {0}: {1}")]
|
||||
Redaction(ruma::OwnedServerName, ruma::canonical_json::RedactionError),
|
||||
#[error("{0:?}: {1}")]
|
||||
Request(ErrorKind, Cow<'static, str>, http::StatusCode),
|
||||
#[error(transparent)]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::{borrow::Borrow, collections::BTreeSet};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use futures::{
|
||||
Future,
|
||||
@@ -824,7 +824,7 @@ struct GetThirdPartyInvite {
|
||||
|
||||
let prev_event_is_create_event = prev_events
|
||||
.next()
|
||||
.is_some_and(|event_id| event_id.borrow() == create_room.event_id().borrow());
|
||||
.is_some_and(|event_id| event_id == create_room.event_id());
|
||||
let no_more_prev_events = prev_events.next().is_none();
|
||||
|
||||
if prev_event_is_create_event && no_more_prev_events {
|
||||
|
||||
@@ -33,7 +33,7 @@ pub fn unstable_features() -> BTreeMap<String, bool> {
|
||||
BTreeMap::from_iter([
|
||||
// query mutual rooms (https://github.com/matrix-org/matrix-spec-proposals/pull/2666)
|
||||
// Expected for spec v1.19
|
||||
("uk.half-shot.msc2666.query_mutual_rooms.stable".to_owned(), true),
|
||||
("uk.half-shot.msc2666.query_mutual_rooms".to_owned(), true),
|
||||
// Simplified Sliding sync (https://github.com/matrix-org/matrix-spec-proposals/pull/4186)
|
||||
// Expected for spec v1.19
|
||||
("org.matrix.simplified_msc3575".to_owned(), true),
|
||||
|
||||
@@ -73,7 +73,7 @@ async fn worker(self: Arc<Self>) -> Result {
|
||||
&& self
|
||||
.services
|
||||
.users
|
||||
.list_local_users()
|
||||
.stream_local_users()
|
||||
.ready_filter(|user| *user != self.services.globals.server_user)
|
||||
.next()
|
||||
.await
|
||||
|
||||
@@ -315,7 +315,8 @@ async fn migrate(services: &Services) -> Result<()> {
|
||||
async fn db_lt_12(services: &Services) -> Result<()> {
|
||||
for username in &services
|
||||
.users
|
||||
.list_local_users()
|
||||
.stream_local_users()
|
||||
.ready_filter(|user| services.globals.user_is_local(user))
|
||||
.collect::<Vec<OwnedUserId>>()
|
||||
.await
|
||||
{
|
||||
@@ -394,7 +395,8 @@ async fn db_lt_12(services: &Services) -> Result<()> {
|
||||
async fn db_lt_13(services: &Services) -> Result<()> {
|
||||
for username in &services
|
||||
.users
|
||||
.list_local_users()
|
||||
.stream_local_users()
|
||||
.ready_filter(|user| services.globals.user_is_local(user))
|
||||
.collect::<Vec<OwnedUserId>>()
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -182,7 +182,7 @@ pub async fn unset_all_presence(&self) {
|
||||
for user_id in &self
|
||||
.services
|
||||
.users
|
||||
.list_local_users()
|
||||
.stream_local_users()
|
||||
.collect::<Vec<OwnedUserId>>()
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use conduwuit::{
|
||||
Err, Result, debug_error, debug_warn, err, error, info, trace,
|
||||
utils::{self, ReadyExt, stream::TryIgnore},
|
||||
utils::{self, stream::TryIgnore},
|
||||
warn,
|
||||
};
|
||||
use database::{Deserialized, Json};
|
||||
@@ -557,18 +557,6 @@ pub fn stream_local_users(&self) -> impl Stream<Item = OwnedUserId> + Send {
|
||||
self.db.userid_password.keys().ignore_err()
|
||||
}
|
||||
|
||||
/// Returns a list of active local users.
|
||||
///
|
||||
/// A user account is considered `local` if the associated password is not
|
||||
/// empty.
|
||||
pub fn list_local_users(&self) -> impl Stream<Item = OwnedUserId> + Send + '_ {
|
||||
self.db
|
||||
.userid_password
|
||||
.stream()
|
||||
.ignore_err()
|
||||
.ready_filter_map(|(u, p): (OwnedUserId, &[u8])| (!p.is_empty()).then_some(u))
|
||||
}
|
||||
|
||||
/// Set a user's password.
|
||||
pub async fn set_password(&self, user_id: &UserId, password: HashedPassword) -> Result {
|
||||
self.status(user_id).await.ensure_active()?;
|
||||
|
||||
@@ -214,11 +214,6 @@ button, a.button {
|
||||
text-align: center;
|
||||
margin: 0.5rem 0;
|
||||
|
||||
&:enabled:hover {
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: lightgray;
|
||||
background-color: gray;
|
||||
@@ -226,6 +221,11 @@ button, a.button {
|
||||
|
||||
&:not(:disabled) {
|
||||
transition: linear color, background-color 0.1s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&:visited {
|
||||
@@ -341,6 +341,10 @@ ul.bullet-separated {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.error-body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ Your account
|
||||
Your account has no associated email address.
|
||||
{% endif %}
|
||||
{% if email_requirement.may_change() %}
|
||||
<a href="email/change/">Change your email</a>\
|
||||
<a href="email/change/">Change your email</a>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -20,7 +20,7 @@ Change your password
|
||||
</div>
|
||||
{% when ChangePasswordBody::Success %}
|
||||
<p>
|
||||
Your password has been changed successfully. <a href="{{ crate::ROUTE_PREFIX }}/account/">Back</a>
|
||||
Your password has been changed successfully.
|
||||
</p>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
{% endif %}
|
||||
|
||||
<pre style="white-space: pre-wrap"><code>{{ error }}</code></pre>
|
||||
<a href="{{ crate::ROUTE_PREFIX }}/account/">Back to account settings</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ Log in
|
||||
</p>
|
||||
<button type="submit">Log in</button>
|
||||
</form>
|
||||
{% if let Some(error) = login_error %}
|
||||
<small class="error">{{ error }}</small>
|
||||
{% endif %}
|
||||
<div class="centered-links">
|
||||
{% if registration_available %}
|
||||
{% let query = next.as_ref().map(serde_urlencoded::to_string).transpose().unwrap().unwrap_or_default() %}
|
||||
@@ -67,6 +70,9 @@ Log in
|
||||
</p>
|
||||
<button type="submit">Continue</button>
|
||||
</form>
|
||||
{% if let Some(error) = login_error %}
|
||||
<small class="error">{{ error }}</small>
|
||||
{% endif %}
|
||||
<div class="centered-links">
|
||||
<a href="{{ crate::ROUTE_PREFIX }}/account/password/reset/">Forgot your password?</a>
|
||||
</div>
|
||||
@@ -74,8 +80,5 @@ Log in
|
||||
<a class="button" href="{{ redirect_url }}">Continue</a>
|
||||
{% endmatch %}
|
||||
{% endmatch %}
|
||||
{% if let Some(error) = login_error %}
|
||||
<small class="error">{{ error }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
|
||||
@@ -27,6 +27,7 @@ Reset your password
|
||||
<p>
|
||||
To reset your password, contact your homeserver's administrator.
|
||||
</p>
|
||||
<a href="{{ crate::ROUTE_PREFIX }}/account/">Back to account settings</a>
|
||||
{% endmatch %}
|
||||
</div>
|
||||
{%- endblock -%}
|
||||
|
||||
Reference in New Issue
Block a user