pl-fe: fix simple policy mrf management
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -188,18 +188,36 @@ const pleromaSchema = coerceObject({
|
|||||||
federation: coerceObject({
|
federation: coerceObject({
|
||||||
enabled: v.fallback(v.boolean(), true), // Assume true unless explicitly false
|
enabled: v.fallback(v.boolean(), true), // Assume true unless explicitly false
|
||||||
mrf_policies: v.fallback(v.optional(v.array(v.string())), undefined),
|
mrf_policies: v.fallback(v.optional(v.array(v.string())), undefined),
|
||||||
mrf_simple: coerceObject({
|
mrf_simple: coerceObject(v.entriesFromList(
|
||||||
accept: v.fallback(v.array(v.string()), []),
|
[
|
||||||
avatar_removal: v.fallback(v.array(v.string()), []),
|
'accept',
|
||||||
banner_removal: v.fallback(v.array(v.string()), []),
|
'avatar_removal',
|
||||||
federated_timeline_removal: v.fallback(v.array(v.string()), []),
|
'banner_removal',
|
||||||
followers_only: v.fallback(v.array(v.string()), []),
|
'federated_timeline_removal',
|
||||||
media_nsfw: v.fallback(v.array(v.string()), []),
|
'followers_only',
|
||||||
media_removal: v.fallback(v.array(v.string()), []),
|
'media_nsfw',
|
||||||
reject: v.fallback(v.array(v.string()), []),
|
'media_removal',
|
||||||
reject_deletes: v.fallback(v.array(v.string()), []),
|
'reject',
|
||||||
report_removal: v.fallback(v.array(v.string()), []),
|
'reject_deletes',
|
||||||
}),
|
'report_removal',
|
||||||
|
],
|
||||||
|
v.fallback(v.array(v.string()), []),
|
||||||
|
)),
|
||||||
|
mrf_simple_info: coerceObject(v.entriesFromList(
|
||||||
|
[
|
||||||
|
'accept',
|
||||||
|
'avatar_removal',
|
||||||
|
'banner_removal',
|
||||||
|
'federated_timeline_removal',
|
||||||
|
'followers_only',
|
||||||
|
'media_nsfw',
|
||||||
|
'media_removal',
|
||||||
|
'reject',
|
||||||
|
'reject_deletes',
|
||||||
|
'report_removal',
|
||||||
|
],
|
||||||
|
v.fallback(v.array(v.tuple([v.string(), v.string()])), []),
|
||||||
|
)),
|
||||||
}),
|
}),
|
||||||
fields_limits: coerceObject({
|
fields_limits: coerceObject({
|
||||||
max_fields: v.fallback(v.pipe(v.number(), v.integer(), v.minValue(0)), 4),
|
max_fields: v.fallback(v.pipe(v.number(), v.integer(), v.minValue(0)), 4),
|
||||||
|
|||||||
@ -1,26 +1,33 @@
|
|||||||
|
import { mrfSimpleSchema, type MRFSimple } from 'pl-fe/schemas/pleroma';
|
||||||
import ConfigDB from 'pl-fe/utils/config-db';
|
import ConfigDB from 'pl-fe/utils/config-db';
|
||||||
|
|
||||||
import { fetchConfig, updateConfig } from './admin';
|
import { fetchConfig, updateConfig } from './admin';
|
||||||
|
|
||||||
import type { MRFSimple } from 'pl-fe/schemas/pleroma';
|
|
||||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||||
|
|
||||||
const simplePolicyMerge = (simplePolicy: MRFSimple, host: string, restrictions: Record<string, any>) => {
|
const simplePolicyMerge = (simplePolicy: Partial<MRFSimple>, host: string, restrictions: Record<string, any>): MRFSimple => {
|
||||||
const entries = Object.entries(simplePolicy).map(([key, hosts]) => {
|
const entries = Object.entries(simplePolicy).map(([key, hosts]) => {
|
||||||
const isRestricted = restrictions[key];
|
const isRestricted = restrictions[key];
|
||||||
|
|
||||||
const set = new Set(hosts);
|
hosts = [...hosts];
|
||||||
|
|
||||||
if (isRestricted) {
|
if (isRestricted) {
|
||||||
set.add(host);
|
if (!hosts.some((tuple) => tuple[0] === host)) {
|
||||||
|
hosts.push([host, '']);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
set.delete(host);
|
hosts = hosts.filter((tuple) => tuple[0] !== host);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [key, [...set]];
|
return [key, hosts];
|
||||||
});
|
});
|
||||||
|
|
||||||
return Object.fromEntries(entries);
|
return Object.fromEntries([
|
||||||
|
...Object.keys(
|
||||||
|
(mrfSimpleSchema as any).wrapped.pipe[2].entries as typeof mrfSimpleSchema.entries,
|
||||||
|
).map((key) => [key, []]),
|
||||||
|
...entries,
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateMrf = (host: string, restrictions: Record<string, any>) =>
|
const updateMrf = (host: string, restrictions: Record<string, any>) =>
|
||||||
|
|||||||
@ -47,7 +47,7 @@ const FederationRestrictionsPage = () => {
|
|||||||
|
|
||||||
<div className='pt-4'>
|
<div className='pt-4'>
|
||||||
<ScrollableList emptyMessageText={emptyMessage}>
|
<ScrollableList emptyMessageText={emptyMessage}>
|
||||||
{hosts.map((host) => <RestrictedInstance key={host} host={host} />)}
|
{hosts.map(([host]) => <RestrictedInstance key={host} host={host} />)}
|
||||||
</ScrollableList>
|
</ScrollableList>
|
||||||
</div>
|
</div>
|
||||||
</Column>
|
</Column>
|
||||||
|
|||||||
@ -32,9 +32,8 @@ const getConfigValue = (instanceConfig: Array<any>, key: string) => {
|
|||||||
const importConfigs = (state: State, configs: PleromaConfig['configs']) => {
|
const importConfigs = (state: State, configs: PleromaConfig['configs']) => {
|
||||||
// FIXME: This is pretty hacked together. Need to make a cleaner map.
|
// FIXME: This is pretty hacked together. Need to make a cleaner map.
|
||||||
const config = ConfigDB.find(configs, ':pleroma', ':instance');
|
const config = ConfigDB.find(configs, ':pleroma', ':instance');
|
||||||
const simplePolicy = ConfigDB.toSimplePolicy(configs);
|
|
||||||
|
|
||||||
if (!config && !simplePolicy) return state;
|
if (!config) return state;
|
||||||
|
|
||||||
if (config) {
|
if (config) {
|
||||||
const value = config.value || [];
|
const value = config.value || [];
|
||||||
@ -47,10 +46,6 @@ const importConfigs = (state: State, configs: PleromaConfig['configs']) => {
|
|||||||
approval_required: approvalRequired ?? state.registrations.approval_required,
|
approval_required: approvalRequired ?? state.registrations.approval_required,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simplePolicy) {
|
|
||||||
state.pleroma.metadata.federation.mrf_simple = simplePolicy;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAuthFetch = (state: State) => {
|
const handleAuthFetch = (state: State) => {
|
||||||
|
|||||||
@ -2,6 +2,11 @@ import * as v from 'valibot';
|
|||||||
|
|
||||||
import { coerceObject } from './utils';
|
import { coerceObject } from './utils';
|
||||||
|
|
||||||
|
const mrfSimpleInstanceSchema = v.pipe(v.any(), v.transform((value) => {
|
||||||
|
if (typeof value === 'string') return [value, ''];
|
||||||
|
return value.tuple;
|
||||||
|
}), v.tuple([v.string(), v.string()]));
|
||||||
|
|
||||||
const mrfSimpleSchema = coerceObject(v.entriesFromList(
|
const mrfSimpleSchema = coerceObject(v.entriesFromList(
|
||||||
[
|
[
|
||||||
'accept',
|
'accept',
|
||||||
@ -15,7 +20,7 @@ const mrfSimpleSchema = coerceObject(v.entriesFromList(
|
|||||||
'reject_deletes',
|
'reject_deletes',
|
||||||
'report_removal',
|
'report_removal',
|
||||||
],
|
],
|
||||||
v.fallback(v.array(v.string()), []),
|
v.fallback(v.array(mrfSimpleInstanceSchema), []),
|
||||||
));
|
));
|
||||||
|
|
||||||
type MRFSimple = v.InferOutput<typeof mrfSimpleSchema>;
|
type MRFSimple = v.InferOutput<typeof mrfSimpleSchema>;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
// import { getLocale } from 'pl-fe/actions/settings';
|
|
||||||
import { Entities } from 'pl-fe/entity-store/entities';
|
import { Entities } from 'pl-fe/entity-store/entities';
|
||||||
import { useSettingsStore } from 'pl-fe/stores/settings';
|
import { useSettingsStore } from 'pl-fe/stores/settings';
|
||||||
import { getDomain } from 'pl-fe/utils/accounts';
|
import { getDomain } from 'pl-fe/utils/accounts';
|
||||||
@ -245,8 +244,8 @@ const makeGetOtherAccounts = () => createSelector([
|
|||||||
|
|
||||||
const getSimplePolicy = createSelector([
|
const getSimplePolicy = createSelector([
|
||||||
(state: RootState) => state.admin.configs,
|
(state: RootState) => state.admin.configs,
|
||||||
(state: RootState) => state.instance.pleroma.metadata.federation.mrf_simple,
|
(state: RootState) => state.instance.pleroma.metadata.federation.mrf_simple_info,
|
||||||
], (configs, instancePolicy) => ({
|
], (configs, instancePolicy): MRFSimple => ({
|
||||||
...instancePolicy,
|
...instancePolicy,
|
||||||
...ConfigDB.toSimplePolicy(configs),
|
...ConfigDB.toSimplePolicy(configs),
|
||||||
}));
|
}));
|
||||||
@ -265,7 +264,7 @@ const getRemoteInstanceFederation = (state: RootState, host: string): HostFedera
|
|||||||
const simplePolicy = getSimplePolicy(state);
|
const simplePolicy = getSimplePolicy(state);
|
||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
Object.entries(simplePolicy).map(([key, hosts]) => [key, hosts.includes(host)]),
|
Object.entries(simplePolicy).map(([key, hosts]) => [key, hosts.some(entry => entry[0] === host)]),
|
||||||
) as HostFederation;
|
) as HostFederation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import trimStart from 'lodash/trimStart';
|
import trimStart from 'lodash/trimStart';
|
||||||
import * as v from 'valibot';
|
import * as v from 'valibot';
|
||||||
|
|
||||||
import { mrfSimpleSchema } from 'pl-fe/schemas/pleroma';
|
import { mrfSimpleSchema, type MRFSimple } from 'pl-fe/schemas/pleroma';
|
||||||
|
|
||||||
import type { PleromaConfig } from 'pl-api';
|
import type { PleromaConfig } from 'pl-api';
|
||||||
|
|
||||||
@ -16,13 +16,14 @@ const find = (
|
|||||||
config.group === group && config.key === key,
|
config.group === group && config.key === key,
|
||||||
);
|
);
|
||||||
|
|
||||||
const toSimplePolicy = (configs: PleromaConfig['configs']) => {
|
const toSimplePolicy = (configs: PleromaConfig['configs']): Partial<MRFSimple> => {
|
||||||
const config = find(configs, ':pleroma', ':mrf_simple');
|
const config = find(configs, ':pleroma', ':mrf_simple');
|
||||||
|
|
||||||
const reducer = (acc: Record<string, any>, curr: Record<string, any>) => {
|
const reducer = (acc: Record<string, any>, curr: Record<string, any>) => {
|
||||||
const key = curr.tuple?.[0] as string;
|
const key = curr.tuple?.[0] as string;
|
||||||
const hosts = curr.tuple?.[1] as Array<string>;
|
const hosts = curr.tuple?.[1] as Array<string>;
|
||||||
return acc[trimStart(key, ':')] = hosts;
|
acc[trimStart(key, ':')] = hosts;
|
||||||
|
return acc;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (config) {
|
if (config) {
|
||||||
@ -30,12 +31,12 @@ const toSimplePolicy = (configs: PleromaConfig['configs']) => {
|
|||||||
const result = value.reduce(reducer, {});
|
const result = value.reduce(reducer, {});
|
||||||
return v.parse(mrfSimpleSchema, result);
|
return v.parse(mrfSimpleSchema, result);
|
||||||
} else {
|
} else {
|
||||||
return v.parse(mrfSimpleSchema, {});
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const fromSimplePolicy = (simplePolicy: Policy) => {
|
const fromSimplePolicy = (simplePolicy: Policy) => {
|
||||||
const mapper = ([key, hosts]: [key: string, hosts: Array<string>]) => ({ tuple: [`:${key}`, hosts] });
|
const mapper = ([key, hosts]: [key: string, hosts: Array<[string, string]>]) => ({ tuple: [`:${key}`, hosts.map(host => ({ tuple: host }))] });
|
||||||
|
|
||||||
const value = Object.entries(simplePolicy).map(mapper);
|
const value = Object.entries(simplePolicy).map(mapper);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user