mirror of
https://github.com/element-hq/matrix-authentication-service.git
synced 2026-10-23 10:53:37 +00:00
Add a registrationToken GraphQL query for anonymous token lookup
The registration form needs to know, before the user submits anything, whether the code they were handed is usable and which identity it pins. The query only returns whether the token is valid and the username and email it was issued for, never the admin-only details.
This commit is contained in:
2 files changed
+70
No files matched your search
@@ -28,6 +28,18 @@ enum UsernameUnavailableReason {
|
||||
Invalid,
|
||||
}
|
||||
|
||||
/// Public information about a registration token, returned by anonymous lookup.
|
||||
/// Does not expose admin details like usage counts or expiration.
|
||||
#[derive(SimpleObject)]
|
||||
struct RegistrationTokenInfo {
|
||||
/// Whether the token is currently valid for registration.
|
||||
valid: bool,
|
||||
/// A username imposed by this token, if any.
|
||||
username: Option<String>,
|
||||
/// An email imposed by this token, if any.
|
||||
email: Option<String>,
|
||||
}
|
||||
|
||||
/// The result of a username availability check.
|
||||
#[derive(SimpleObject)]
|
||||
struct UsernameAvailability {
|
||||
@@ -168,6 +180,35 @@ impl UserQuery {
|
||||
})
|
||||
}
|
||||
|
||||
/// Look up a registration token by its string value.
|
||||
///
|
||||
/// Returns public information about the token (validity, imposed
|
||||
/// username/email). Returns `null` if the token does not exist.
|
||||
///
|
||||
/// This query is accessible to anonymous users, as it is used during
|
||||
/// the registration flow.
|
||||
async fn registration_token(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
token: String,
|
||||
) -> Result<Option<RegistrationTokenInfo>, async_graphql::Error> {
|
||||
let state = ctx.state();
|
||||
let mut repo = state.repository().await?;
|
||||
|
||||
let registration_token = repo.user_registration_token().find_by_token(&token).await?;
|
||||
repo.cancel().await?;
|
||||
|
||||
let Some(registration_token) = registration_token else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
Ok(Some(RegistrationTokenInfo {
|
||||
valid: registration_token.is_valid(state.clock().now()),
|
||||
username: registration_token.username,
|
||||
email: registration_token.email,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Fetch a user by its username.
|
||||
async fn user_by_username(
|
||||
&self,
|
||||
|
||||
@@ -1194,6 +1194,16 @@ type Query {
|
||||
"""
|
||||
usernameAvailable(username: String!): UsernameAvailability!
|
||||
"""
|
||||
Look up a registration token by its string value.
|
||||
|
||||
Returns public information about the token (validity, imposed
|
||||
username/email). Returns `null` if the token does not exist.
|
||||
|
||||
This query is accessible to anonymous users, as it is used during
|
||||
the registration flow.
|
||||
"""
|
||||
registrationToken(token: String!): RegistrationTokenInfo
|
||||
"""
|
||||
Fetch a user by its username.
|
||||
"""
|
||||
userByUsername(username: String!): User
|
||||
@@ -1271,6 +1281,25 @@ type Query {
|
||||
viewerSession: ViewerSession!
|
||||
}
|
||||
|
||||
"""
|
||||
Public information about a registration token, returned by anonymous lookup.
|
||||
Does not expose admin details like usage counts or expiration.
|
||||
"""
|
||||
type RegistrationTokenInfo {
|
||||
"""
|
||||
Whether the token is currently valid for registration.
|
||||
"""
|
||||
valid: Boolean!
|
||||
"""
|
||||
A username imposed by this token, if any.
|
||||
"""
|
||||
username: String
|
||||
"""
|
||||
An email imposed by this token, if any.
|
||||
"""
|
||||
email: String
|
||||
}
|
||||
|
||||
"""
|
||||
The input for the `removeEmail` mutation
|
||||
"""
|
||||
|
||||
Reference in new issue
Block a user