[Adminitration] Allow registrations: 3 modes = "close", "allowed", "moderate" - #877

This commit is contained in:
Laurent GAY
2025-09-03 21:07:33 +02:00
parent 8f8aa0ffbe
commit 3e4899c8e4
28 changed files with 526 additions and 19 deletions

View File

@@ -229,13 +229,19 @@ export function useRegistrationConfig() {
const { result, error, loading, onResult } = useQuery<{
config: Pick<
IConfig,
"registrationsOpen" | "registrationsAllowlist" | "auth"
| "registrationsOpen"
| "registrationsModeration"
| "registrationsAllowlist"
| "auth"
>;
}>(CONFIG);
const registrationsOpen = computed(
() => result.value?.config?.registrationsOpen
);
const registrationsModeration = computed(
() => result.value?.config?.registrationsModeration
);
const registrationsAllowlist = computed(
() => result.value?.config?.registrationsAllowlist
);
@@ -244,6 +250,7 @@ export function useRegistrationConfig() {
);
return {
registrationsOpen,
registrationsModeration,
registrationsAllowlist,
databaseLogin,
error,

View File

@@ -225,6 +225,7 @@ export const ADMIN_SETTINGS_FRAGMENT = gql`
instancePrivacyPolicyUrl
instanceRules
registrationsOpen
registrationsModeration
instanceLanguages
}
`;
@@ -258,6 +259,7 @@ export const SAVE_ADMIN_SETTINGS = gql`
$instancePrivacyPolicyUrl: String
$instanceRules: String
$registrationsOpen: Boolean
$registrationsModeration: Boolean
$instanceLanguages: [String]
) {
saveAdminSettings(
@@ -279,6 +281,7 @@ export const SAVE_ADMIN_SETTINGS = gql`
instancePrivacyPolicyUrl: $instancePrivacyPolicyUrl
instanceRules: $instanceRules
registrationsOpen: $registrationsOpen
registrationsModeration: $registrationsModeration
instanceLanguages: $instanceLanguages
) {
...adminSettingsFragment

View File

@@ -11,6 +11,7 @@ export const CONFIG = gql`
version
federating
registrationsOpen
registrationsModeration
registrationsAllowlist
demoMode
longEvents
@@ -205,6 +206,7 @@ export const ABOUT = gql`
contact
languages
registrationsOpen
registrationsModeration
registrationsAllowlist
anonymous {
participation {

View File

@@ -975,6 +975,7 @@
"Registration is allowed, anyone can register.": "Registration is allowed, anyone can register.",
"Registration is closed.": "Registration is closed.",
"Registration is currently closed.": "Registration is currently closed.",
"Registration is moderated, new user must be validated.": "Registration is moderated, new user must be validated.",
"Registrations": "Registrations",
"Registrations are restricted by allowlisting.": "Registrations are restricted by allowlisting.",
"Reject": "Reject",
@@ -1698,4 +1699,4 @@
"{user}'s follow request was accepted": "{user}'s follow request was accepted",
"{user}'s follow request was rejected": "{user}'s follow request was rejected",
"\u00a9 The OpenStreetMap Contributors": "\u00a9 The OpenStreetMap Contributors"
}
}

View File

@@ -39,5 +39,6 @@ export interface IAdminSettings {
instancePrivacyPolicyUrl: string | null;
instanceRules: string;
registrationsOpen: boolean;
registrationsModeration: boolean;
instanceLanguages: string[];
}

View File

@@ -43,6 +43,7 @@ export interface IConfig {
secondaryColor: string;
registrationsOpen: boolean;
registrationsModeration: boolean;
registrationsAllowlist: boolean;
demoMode: boolean;
longEvents: boolean;

View File

@@ -11,6 +11,12 @@ export enum InstancePrivacyType {
CUSTOM = "CUSTOM",
}
export enum registrationsModeType {
CLOSE = "CLOSE",
OPEN = "OPEN",
MODERATED = "MODERATED",
}
export enum ICurrentUserRole {
USER = "USER",
MODERATOR = "MODERATOR",

View File

@@ -123,17 +123,36 @@
</div>
-->
<o-field :label="t('Allow registrations')">
<o-switch v-model="settingsToWrite.registrationsOpen">
<p
class="prose dark:prose-invert"
v-if="settingsToWrite.registrationsOpen"
>
{{ t("Registration is allowed, anyone can register.") }}
</p>
<p class="prose dark:prose-invert" v-else>
{{ t("Registration is closed.") }}
</p>
</o-switch>
<fieldset>
<o-field>
<o-radio
v-model="registrationsMode"
name="registrationsModeType"
:native-value="registrationsModeType.CLOSE"
>{{ t("Registration is closed.") }}</o-radio
>
</o-field>
<o-field>
<o-radio
v-model="registrationsMode"
name="registrationsModeType"
:native-value="registrationsModeType.OPEN"
>{{
t("Registration is allowed, anyone can register.")
}}</o-radio
>
</o-field>
<o-field>
<o-radio
v-model="registrationsMode"
name="registrationsModeType"
:native-value="registrationsModeType.MODERATED"
>{{
t("Registration is moderated, new user must be validated.")
}}</o-radio
>
</o-field>
</fieldset>
</o-field>
<div class="field flex flex-col">
<label class="" for="instance-languages">{{
@@ -447,7 +466,11 @@ import {
SAVE_ADMIN_SETTINGS,
LANGUAGES,
} from "@/graphql/admin";
import { InstancePrivacyType, InstanceTermsType } from "@/types/enums";
import {
InstancePrivacyType,
InstanceTermsType,
registrationsModeType,
} from "@/types/enums";
import { IAdminSettings, ILanguage } from "@/types/admin.model";
import RouteName from "@/router/name";
import { useMutation, useQuery } from "@vue/apollo-composable";
@@ -485,6 +508,7 @@ const defaultAdminSettings: IAdminSettings = {
instancePrivacyPolicyUrl: null,
instanceRules: "",
registrationsOpen: false,
registrationsModeration: false,
instanceLanguages: [],
};
@@ -533,6 +557,32 @@ watch(adminSettings, () => {
const filteredLanguages = ref<string[]>([]);
const registrationsMode = computed({
get() {
if (settingsToWrite.value.registrationsOpen == true) {
if (settingsToWrite.value.registrationsModeration == true) {
return registrationsModeType.MODERATED;
} else {
return registrationsModeType.OPEN;
}
} else {
return registrationsModeType.CLOSE;
}
},
set(newMode: string) {
if (newMode == registrationsModeType.OPEN) {
settingsToWrite.value.registrationsOpen = true;
settingsToWrite.value.registrationsModeration = false;
} else if (newMode == registrationsModeType.MODERATED) {
settingsToWrite.value.registrationsOpen = true;
settingsToWrite.value.registrationsModeration = true;
} else {
settingsToWrite.value.registrationsOpen = false;
settingsToWrite.value.registrationsModeration = false;
}
},
});
const instanceLanguages = computed({
get() {
const languageCodes = [...(adminSettings.value?.instanceLanguages ?? [])];

View File

@@ -212,7 +212,11 @@ const EventParticipationCard = defineAsyncComponent(
const { result: aboutConfigResult } = useQuery<{
config: Pick<
IConfig,
"name" | "description" | "slogan" | "registrationsOpen"
| "name"
| "description"
| "slogan"
| "registrationsOpen"
| "registrationsModeration"
>;
}>(CONFIG);

View File

@@ -162,7 +162,10 @@ const apollo = useApolloClient();
const configQuery = useQuery<{
config: Pick<
IConfig,
"auth" | "registrationsOpen" | "registrationsAllowlist"
| "auth"
| "registrationsOpen"
| "registrationsModeration"
| "registrationsAllowlist"
>;
}>(CONFIG);