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

Commit 8737d6f

Browse files
committed
graphql: Expose CAPTCHA config and whether password registration is enabled
1 parent 4a275fa commit 8737d6f

File tree

4 files changed

+161
-1
lines changed

4 files changed

+161
-1
lines changed

crates/handlers/src/graphql/model/site_config.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@
1414

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

17-
use async_graphql::{ComplexObject, SimpleObject, ID};
17+
use async_graphql::{ComplexObject, Enum, SimpleObject, ID};
1818
use url::Url;
1919

2020
pub const SITE_CONFIG_ID: &str = "site_config";
21+
pub const CAPTCHA_CONFIG_ID: &str = "captcha_config";
2122

2223
#[derive(SimpleObject)]
2324
#[graphql(complex)]
2425
#[allow(clippy::struct_excessive_bools)]
2526
pub struct SiteConfig {
27+
/// The configuration of CAPTCHA provider.
28+
captcha_config: Option<CaptchaConfig>,
29+
2630
/// The server name of the homeserver.
2731
server_name: String,
2832

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

54+
/// Whether passwords are enabled and users can register using a password.
55+
password_registration_enabled: bool,
56+
5057
/// Minimum password complexity, from 0 to 4, in terms of a zxcvbn score.
5158
/// The exact scorer (including dictionaries and other data tables)
5259
/// in use is <https://crates.io/crates/zxcvbn>.
5360
minimum_password_complexity: u8,
5461
}
5562

63+
#[derive(SimpleObject)]
64+
#[graphql(complex)]
65+
pub struct CaptchaConfig {
66+
/// Which Captcha service is being used
67+
pub service: CaptchaService,
68+
69+
/// The site key used by the instance
70+
pub site_key: String,
71+
}
72+
73+
/// Which Captcha service is being used
74+
#[derive(Enum, Debug, Clone, Copy, PartialEq, Eq)]
75+
pub enum CaptchaService {
76+
RecaptchaV2,
77+
CloudflareTurnstile,
78+
HCaptcha,
79+
}
80+
5681
#[ComplexObject]
5782
impl SiteConfig {
5883
/// The ID of the site configuration.
@@ -66,6 +91,7 @@ impl SiteConfig {
6691
/// [`mas_data_model:::SiteConfig`].
6792
pub fn new(data_model: &mas_data_model::SiteConfig) -> Self {
6893
Self {
94+
captcha_config: data_model.captcha.as_ref().map(CaptchaConfig::new),
6995
server_name: data_model.server_name.clone(),
7096
policy_uri: data_model.policy_uri.clone(),
7197
tos_uri: data_model.tos_uri.clone(),
@@ -74,7 +100,32 @@ impl SiteConfig {
74100
display_name_change_allowed: data_model.displayname_change_allowed,
75101
password_login_enabled: data_model.password_login_enabled,
76102
password_change_allowed: data_model.password_change_allowed,
103+
password_registration_enabled: data_model.password_registration_enabled,
77104
minimum_password_complexity: data_model.minimum_password_complexity,
78105
}
79106
}
80107
}
108+
109+
#[ComplexObject]
110+
impl CaptchaConfig {
111+
pub async fn id(&self) -> ID {
112+
CAPTCHA_CONFIG_ID.into()
113+
}
114+
}
115+
116+
impl CaptchaConfig {
117+
/// Create a new [`CaptchaConfig`] from the data model
118+
/// [`mas_data_model:::CaptchaConfig`].
119+
pub fn new(data_model: &mas_data_model::CaptchaConfig) -> Self {
120+
Self {
121+
service: match data_model.service {
122+
mas_data_model::CaptchaService::RecaptchaV2 => CaptchaService::RecaptchaV2,
123+
mas_data_model::CaptchaService::CloudflareTurnstile => {
124+
CaptchaService::CloudflareTurnstile
125+
}
126+
mas_data_model::CaptchaService::HCaptcha => CaptchaService::HCaptcha,
127+
},
128+
site_key: data_model.site_key.clone(),
129+
}
130+
}
131+
}

frontend/schema.graphql

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,27 @@ type BrowserSessionEdge {
300300
cursor: String!
301301
}
302302

303+
type CaptchaConfig {
304+
"""
305+
Which Captcha service is being used
306+
"""
307+
service: CaptchaService!
308+
"""
309+
The site key used by the instance
310+
"""
311+
siteKey: String!
312+
id: ID!
313+
}
314+
315+
"""
316+
Which Captcha service is being used
317+
"""
318+
enum CaptchaService {
319+
RECAPTCHA_V2
320+
CLOUDFLARE_TURNSTILE
321+
H_CAPTCHA
322+
}
323+
303324
"""
304325
A compat session represents a client session which used the legacy Matrix
305326
login API.
@@ -1414,6 +1435,10 @@ enum SetPrimaryEmailStatus {
14141435
}
14151436

14161437
type SiteConfig implements Node {
1438+
"""
1439+
The configuration of CAPTCHA provider.
1440+
"""
1441+
captchaConfig: CaptchaConfig
14171442
"""
14181443
The server name of the homeserver.
14191444
"""
@@ -1447,6 +1472,10 @@ type SiteConfig implements Node {
14471472
"""
14481473
passwordChangeAllowed: Boolean!
14491474
"""
1475+
Whether passwords are enabled and users can register using a password.
1476+
"""
1477+
passwordRegistrationEnabled: Boolean!
1478+
"""
14501479
Minimum password complexity, from 0 to 4, in terms of a zxcvbn score.
14511480
The exact scorer (including dictionaries and other data tables)
14521481
in use is <https://crates.io/crates/zxcvbn>.

frontend/src/gql/graphql.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,22 @@ export type BrowserSessionEdge = {
212212
node: BrowserSession;
213213
};
214214

215+
export type CaptchaConfig = {
216+
__typename?: 'CaptchaConfig';
217+
id: Scalars['ID']['output'];
218+
/** Which Captcha service is being used */
219+
service: CaptchaService;
220+
/** The site key used by the instance */
221+
siteKey: Scalars['String']['output'];
222+
};
223+
224+
/** Which Captcha service is being used */
225+
export enum CaptchaService {
226+
CloudflareTurnstile = 'CLOUDFLARE_TURNSTILE',
227+
HCaptcha = 'H_CAPTCHA',
228+
RecaptchaV2 = 'RECAPTCHA_V2'
229+
}
230+
215231
/**
216232
* A compat session represents a client session which used the legacy Matrix
217233
* login API.
@@ -1063,6 +1079,8 @@ export enum SetPrimaryEmailStatus {
10631079

10641080
export type SiteConfig = Node & {
10651081
__typename?: 'SiteConfig';
1082+
/** The configuration of CAPTCHA provider. */
1083+
captchaConfig?: Maybe<CaptchaConfig>;
10661084
/** Whether users can change their display name. */
10671085
displayNameChangeAllowed: Scalars['Boolean']['output'];
10681086
/** Whether users can change their email. */
@@ -1081,6 +1099,8 @@ export type SiteConfig = Node & {
10811099
passwordChangeAllowed: Scalars['Boolean']['output'];
10821100
/** Whether passwords are enabled for login. */
10831101
passwordLoginEnabled: Scalars['Boolean']['output'];
1102+
/** Whether passwords are enabled and users can register using a password. */
1103+
passwordRegistrationEnabled: Scalars['Boolean']['output'];
10841104
/** The URL to the privacy policy. */
10851105
policyUri?: Maybe<Scalars['Url']['output']>;
10861106
/** The server name of the homeserver. */

frontend/src/gql/schema.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,46 @@ export default {
529529
],
530530
"interfaces": []
531531
},
532+
{
533+
"kind": "OBJECT",
534+
"name": "CaptchaConfig",
535+
"fields": [
536+
{
537+
"name": "id",
538+
"type": {
539+
"kind": "NON_NULL",
540+
"ofType": {
541+
"kind": "SCALAR",
542+
"name": "Any"
543+
}
544+
},
545+
"args": []
546+
},
547+
{
548+
"name": "service",
549+
"type": {
550+
"kind": "NON_NULL",
551+
"ofType": {
552+
"kind": "SCALAR",
553+
"name": "Any"
554+
}
555+
},
556+
"args": []
557+
},
558+
{
559+
"name": "siteKey",
560+
"type": {
561+
"kind": "NON_NULL",
562+
"ofType": {
563+
"kind": "SCALAR",
564+
"name": "Any"
565+
}
566+
},
567+
"args": []
568+
}
569+
],
570+
"interfaces": []
571+
},
532572
{
533573
"kind": "OBJECT",
534574
"name": "CompatSession",
@@ -2570,6 +2610,15 @@ export default {
25702610
"kind": "OBJECT",
25712611
"name": "SiteConfig",
25722612
"fields": [
2613+
{
2614+
"name": "captchaConfig",
2615+
"type": {
2616+
"kind": "OBJECT",
2617+
"name": "CaptchaConfig",
2618+
"ofType": null
2619+
},
2620+
"args": []
2621+
},
25732622
{
25742623
"name": "displayNameChangeAllowed",
25752624
"type": {
@@ -2644,6 +2693,17 @@ export default {
26442693
},
26452694
"args": []
26462695
},
2696+
{
2697+
"name": "passwordRegistrationEnabled",
2698+
"type": {
2699+
"kind": "NON_NULL",
2700+
"ofType": {
2701+
"kind": "SCALAR",
2702+
"name": "Any"
2703+
}
2704+
},
2705+
"args": []
2706+
},
26472707
{
26482708
"name": "policyUri",
26492709
"type": {

0 commit comments

Comments
 (0)