Compare commits

...
Author SHA1 Message Date
François-X. T. d29895cbbb feat: account consent 2026-07-19 17:31:36 -04:00
5 changed files with 41 additions and 5 deletions
@@ -72,6 +72,18 @@
/>
</div>
<div class="hidden" aria-hidden="true">
<input
id="create-account-consent"
v-model="accountConsent"
name="account_consent"
type="checkbox"
tabindex="-1"
autocomplete="off"
/>
<label for="create-account-consent">I agree to receive account updates by email</label>
</div>
<ButtonStyled color="brand">
<button
class="!w-full font-bold"
@@ -97,7 +109,7 @@ import {
StyledInput,
useVIntl,
} from '@modrinth/ui'
import { computed } from 'vue'
import { computed, ref } from 'vue'
import HCaptcha from '@/components/ui/auth/HCaptcha.vue'
@@ -109,7 +121,7 @@ interface AuthGlobals {
interface Props {
globals?: AuthGlobals | null
requiresDob?: boolean
onCompleteSignUp?: () => void
onCompleteSignUp?: (accountConsent: boolean) => void
onSetCaptchaRef?: ((captchaRef: unknown) => void) | undefined
}
@@ -127,6 +139,7 @@ const dateOfBirthModel = defineModel<string | null>('dateOfBirth', { default: ''
const usernameModel = defineModel<string>('username', { default: '' })
const tokenModel = defineModel<string>('token', { default: '' })
const subscribeModel = defineModel<boolean>('subscribe', { default: false })
const accountConsent = ref(false)
const maxInputDate = computed(() => `${new Date().getFullYear()}-12-31`)
@@ -198,7 +211,7 @@ function onCompleteSignUpClick() {
return
}
onCompleteSignUp()
onCompleteSignUp(accountConsent.value)
}
const messages = defineMessages({
@@ -128,7 +128,7 @@ const { data: globals } = useQuery<AuthGlobalsResponse>({
},
})
async function completeOAuthSignUp() {
async function completeOAuthSignUp(accountConsent: boolean) {
startLoading()
try {
if (!oauthFlowState.value) {
@@ -140,6 +140,7 @@ async function completeOAuthSignUp() {
state: oauthFlowState.value,
challenge: token.value,
sign_up_newsletter: subscribe.value,
account_consent: accountConsent,
})
await finishSignIn(res.session)
+2 -1
View File
@@ -250,7 +250,7 @@ function isUsernameTakenValidationError(error: unknown): boolean {
return errorCode === 'username_taken'
}
async function createAccount() {
async function createAccount(accountConsent: boolean) {
startLoading()
try {
const res = await client.labrinth.auth_v2.createAccount({
@@ -259,6 +259,7 @@ async function createAccount() {
email: email.value,
challenge: token.value,
sign_up_newsletter: subscribe.value,
account_consent: accountConsent,
})
await useAuth(res.session)
@@ -1438,6 +1438,19 @@ struct NewOAuthAccount {
pub state: String,
pub challenge: String,
pub sign_up_newsletter: bool,
#[serde(default)]
pub account_consent: bool,
}
fn validate_account_consent(account_consent: bool) -> Result<(), ApiError> {
if account_consent {
info!("account consent trigger, denying");
return Err(ApiError::Request(eyre!(
"Sorry, something went wrong. Please try again"
)));
}
Ok(())
}
/// Create account with OAuth.
@@ -1463,6 +1476,8 @@ pub async fn create_oauth_account(
ApiError::InvalidInput(validation_errors_to_string(err, None))
})?;
validate_account_consent(new_account.account_consent)?;
if !check_hcaptcha(&req, &new_account.challenge).await? {
return Err(ApiError::Turnstile);
}
@@ -1709,6 +1724,8 @@ pub struct NewAccount {
pub email: String,
pub challenge: Option<String>,
pub sign_up_newsletter: Option<bool>,
#[serde(default)]
pub account_consent: bool,
}
#[derive(Debug, Validate)]
@@ -1996,6 +2013,8 @@ pub async fn create_account_with_password(
) -> Result<HttpResponse, ApiError> {
let new_account = new_account.into_inner();
validate_account_consent(new_account.account_consent)?;
if !check_hcaptcha(&req, new_account.challenge.as_deref().unwrap_or(""))
.await?
{
@@ -756,6 +756,7 @@ export namespace Labrinth {
email: string
challenge: string
sign_up_newsletter?: boolean
account_consent?: boolean
}
export type CreateAccountResponse = {
@@ -773,6 +774,7 @@ export namespace Labrinth {
state: string
challenge: string
sign_up_newsletter: boolean
account_consent?: boolean
}
export type CreateOAuthAccountResponse = {