Skip to content
This repository has been archived by the owner on Sep 10, 2024. It is now read-only.

Commit

Permalink
graphql: Expose CAPTCHA config and whether password registration is e…
Browse files Browse the repository at this point in the history
…nabled
  • Loading branch information
reivilibre committed Jul 26, 2024
1 parent 4a275fa commit 8737d6f
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 1 deletion.
53 changes: 52 additions & 1 deletion crates/handlers/src/graphql/model/site_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@

#![allow(clippy::str_to_string)] // ComplexObject macro uses &str.to_string()

use async_graphql::{ComplexObject, SimpleObject, ID};
use async_graphql::{ComplexObject, Enum, SimpleObject, ID};
use url::Url;

pub const SITE_CONFIG_ID: &str = "site_config";
pub const CAPTCHA_CONFIG_ID: &str = "captcha_config";

#[derive(SimpleObject)]
#[graphql(complex)]
#[allow(clippy::struct_excessive_bools)]
pub struct SiteConfig {
/// The configuration of CAPTCHA provider.
captcha_config: Option<CaptchaConfig>,

/// The server name of the homeserver.
server_name: String,

Expand All @@ -47,12 +51,33 @@ pub struct SiteConfig {
/// Whether passwords are enabled and users can change their own passwords.
password_change_allowed: bool,

/// Whether passwords are enabled and users can register using a password.
password_registration_enabled: bool,

/// Minimum password complexity, from 0 to 4, in terms of a zxcvbn score.
/// The exact scorer (including dictionaries and other data tables)
/// in use is <https://crates.io/crates/zxcvbn>.
minimum_password_complexity: u8,
}

#[derive(SimpleObject)]
#[graphql(complex)]
pub struct CaptchaConfig {
/// Which Captcha service is being used
pub service: CaptchaService,

/// The site key used by the instance
pub site_key: String,
}

/// Which Captcha service is being used
#[derive(Enum, Debug, Clone, Copy, PartialEq, Eq)]
pub enum CaptchaService {
RecaptchaV2,
CloudflareTurnstile,
HCaptcha,
}

#[ComplexObject]
impl SiteConfig {
/// The ID of the site configuration.
Expand All @@ -66,6 +91,7 @@ impl SiteConfig {
/// [`mas_data_model:::SiteConfig`].
pub fn new(data_model: &mas_data_model::SiteConfig) -> Self {
Self {
captcha_config: data_model.captcha.as_ref().map(CaptchaConfig::new),
server_name: data_model.server_name.clone(),
policy_uri: data_model.policy_uri.clone(),
tos_uri: data_model.tos_uri.clone(),
Expand All @@ -74,7 +100,32 @@ impl SiteConfig {
display_name_change_allowed: data_model.displayname_change_allowed,
password_login_enabled: data_model.password_login_enabled,
password_change_allowed: data_model.password_change_allowed,
password_registration_enabled: data_model.password_registration_enabled,
minimum_password_complexity: data_model.minimum_password_complexity,
}
}
}

#[ComplexObject]
impl CaptchaConfig {
pub async fn id(&self) -> ID {
CAPTCHA_CONFIG_ID.into()
}
}

impl CaptchaConfig {
/// Create a new [`CaptchaConfig`] from the data model
/// [`mas_data_model:::CaptchaConfig`].
pub fn new(data_model: &mas_data_model::CaptchaConfig) -> Self {
Self {
service: match data_model.service {
mas_data_model::CaptchaService::RecaptchaV2 => CaptchaService::RecaptchaV2,
mas_data_model::CaptchaService::CloudflareTurnstile => {
CaptchaService::CloudflareTurnstile
}
mas_data_model::CaptchaService::HCaptcha => CaptchaService::HCaptcha,
},
site_key: data_model.site_key.clone(),
}
}
}
29 changes: 29 additions & 0 deletions frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,27 @@ type BrowserSessionEdge {
cursor: String!
}

type CaptchaConfig {
"""
Which Captcha service is being used
"""
service: CaptchaService!
"""
The site key used by the instance
"""
siteKey: String!
id: ID!
}

"""
Which Captcha service is being used
"""
enum CaptchaService {
RECAPTCHA_V2
CLOUDFLARE_TURNSTILE
H_CAPTCHA
}

"""
A compat session represents a client session which used the legacy Matrix
login API.
Expand Down Expand Up @@ -1414,6 +1435,10 @@ enum SetPrimaryEmailStatus {
}

type SiteConfig implements Node {
"""
The configuration of CAPTCHA provider.
"""
captchaConfig: CaptchaConfig
"""
The server name of the homeserver.
"""
Expand Down Expand Up @@ -1447,6 +1472,10 @@ type SiteConfig implements Node {
"""
passwordChangeAllowed: Boolean!
"""
Whether passwords are enabled and users can register using a password.
"""
passwordRegistrationEnabled: Boolean!
"""
Minimum password complexity, from 0 to 4, in terms of a zxcvbn score.
The exact scorer (including dictionaries and other data tables)
in use is <https://crates.io/crates/zxcvbn>.
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/gql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,22 @@ export type BrowserSessionEdge = {
node: BrowserSession;
};

export type CaptchaConfig = {
__typename?: 'CaptchaConfig';
id: Scalars['ID']['output'];
/** Which Captcha service is being used */
service: CaptchaService;
/** The site key used by the instance */
siteKey: Scalars['String']['output'];
};

/** Which Captcha service is being used */
export enum CaptchaService {
CloudflareTurnstile = 'CLOUDFLARE_TURNSTILE',
HCaptcha = 'H_CAPTCHA',
RecaptchaV2 = 'RECAPTCHA_V2'
}

/**
* A compat session represents a client session which used the legacy Matrix
* login API.
Expand Down Expand Up @@ -1063,6 +1079,8 @@ export enum SetPrimaryEmailStatus {

export type SiteConfig = Node & {
__typename?: 'SiteConfig';
/** The configuration of CAPTCHA provider. */
captchaConfig?: Maybe<CaptchaConfig>;
/** Whether users can change their display name. */
displayNameChangeAllowed: Scalars['Boolean']['output'];
/** Whether users can change their email. */
Expand All @@ -1081,6 +1099,8 @@ export type SiteConfig = Node & {
passwordChangeAllowed: Scalars['Boolean']['output'];
/** Whether passwords are enabled for login. */
passwordLoginEnabled: Scalars['Boolean']['output'];
/** Whether passwords are enabled and users can register using a password. */
passwordRegistrationEnabled: Scalars['Boolean']['output'];
/** The URL to the privacy policy. */
policyUri?: Maybe<Scalars['Url']['output']>;
/** The server name of the homeserver. */
Expand Down
60 changes: 60 additions & 0 deletions frontend/src/gql/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,46 @@ export default {
],
"interfaces": []
},
{
"kind": "OBJECT",
"name": "CaptchaConfig",
"fields": [
{
"name": "id",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "Any"
}
},
"args": []
},
{
"name": "service",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "Any"
}
},
"args": []
},
{
"name": "siteKey",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "Any"
}
},
"args": []
}
],
"interfaces": []
},
{
"kind": "OBJECT",
"name": "CompatSession",
Expand Down Expand Up @@ -2570,6 +2610,15 @@ export default {
"kind": "OBJECT",
"name": "SiteConfig",
"fields": [
{
"name": "captchaConfig",
"type": {
"kind": "OBJECT",
"name": "CaptchaConfig",
"ofType": null
},
"args": []
},
{
"name": "displayNameChangeAllowed",
"type": {
Expand Down Expand Up @@ -2644,6 +2693,17 @@ export default {
},
"args": []
},
{
"name": "passwordRegistrationEnabled",
"type": {
"kind": "NON_NULL",
"ofType": {
"kind": "SCALAR",
"name": "Any"
}
},
"args": []
},
{
"name": "policyUri",
"type": {
Expand Down

0 comments on commit 8737d6f

Please sign in to comment.