pleroma/src/reducers/instance.ts

119 lines
4 KiB
TypeScript
Raw Normal View History

2023-09-23 18:41:24 -07:00
import { produce } from 'immer';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import { ADMIN_CONFIG_UPDATE_REQUEST, ADMIN_CONFIG_UPDATE_SUCCESS } from 'soapbox/actions/admin';
import { PLEROMA_PRELOAD_IMPORT } from 'soapbox/actions/preload';
2023-09-23 18:41:24 -07:00
import { type Instance, instanceSchema } from 'soapbox/schemas';
import { instanceV1ToV2 } from 'soapbox/schemas/instance';
import KVStore from 'soapbox/storage/kv-store';
2022-11-15 12:46:23 -08:00
import { ConfigDB } from 'soapbox/utils/config-db';
import {
rememberInstance,
fetchInstance,
fetchInstanceV2,
} from '../actions/instance';
import type { AnyAction } from 'redux';
import type { APIEntity } from 'soapbox/types/entities';
2023-09-23 18:41:24 -07:00
const initialState: Instance = instanceSchema.parse({});
const importInstance = (_state: typeof initialState, instance: APIEntity) => {
if (typeof instance.domain === 'string') return instanceSchema.parse(instance);
return instanceV1ToV2.parse(instance);
};
const preloadImport = (state: typeof initialState, action: Record<string, any>, path: string) => {
const instance = action.data[path];
2023-09-23 18:41:24 -07:00
return instance ? importInstance(state, instance) : state;
};
const getConfigValue = (instanceConfig: ImmutableMap<string, any>, key: string) => {
const v = instanceConfig
.find(value => value.getIn(['tuple', 0]) === key);
return v ? v.getIn(['tuple', 1]) : undefined;
};
2022-03-20 16:41:47 -07:00
const importConfigs = (state: typeof initialState, configs: ImmutableList<any>) => {
// FIXME: This is pretty hacked together. Need to make a cleaner map.
const config = ConfigDB.find(configs, ':pleroma', ':instance');
const simplePolicy = ConfigDB.toSimplePolicy(configs);
if (!config && !simplePolicy) return state;
2023-09-23 18:41:24 -07:00
return produce(state, (draft) => {
if (config) {
const value = config.get('value', ImmutableList());
2023-09-23 18:41:24 -07:00
const registrationsOpen = getConfigValue(value, ':registrations_open') as boolean | undefined;
const approvalRequired = getConfigValue(value, ':account_approval_required') as boolean | undefined;
draft.registrations = {
enabled: registrationsOpen ?? draft.registrations.enabled,
approval_required: approvalRequired ?? draft.registrations.approval_required,
};
}
if (simplePolicy) {
2023-09-23 18:41:24 -07:00
draft.pleroma.metadata.federation.mrf_simple = simplePolicy;
}
});
};
const handleAuthFetch = (state: typeof initialState) => {
// Authenticated fetch is enabled, so make the instance appear censored
2023-09-23 18:41:24 -07:00
return {
...state,
title: state.title || '██████',
description: state.description || '████████████',
};
};
const getHost = (instance: { uri: string }) => {
try {
return new URL(instance.uri).host;
} catch {
try {
return new URL(`https://${instance.uri}`).host;
} catch {
return null;
}
}
};
const persistInstance = (instance: { uri: string }, host: string | null = getHost(instance)) => {
if (host) {
KVStore.setItem(`instance:${host}`, instance).catch(console.error);
}
};
const handleInstanceFetchFail = (state: typeof initialState, error: Record<string, any>) => {
if (error.response?.status === 401) {
return handleAuthFetch(state);
} else {
return state;
}
};
export default function instance(state = initialState, action: AnyAction) {
switch (action.type) {
2022-05-11 14:06:35 -07:00
case PLEROMA_PRELOAD_IMPORT:
return preloadImport(state, action, '/api/v1/instance');
case rememberInstance.fulfilled.type:
return importInstance(state, action.payload.instance);
2022-05-11 14:06:35 -07:00
case fetchInstance.fulfilled.type:
case fetchInstanceV2.fulfilled.type:
2022-05-11 14:06:35 -07:00
persistInstance(action.payload);
return importInstance(state, action.payload.instance);
2022-05-11 14:06:35 -07:00
case fetchInstance.rejected.type:
case fetchInstanceV2.rejected.type:
2022-05-11 14:06:35 -07:00
return handleInstanceFetchFail(state, action.error);
case ADMIN_CONFIG_UPDATE_REQUEST:
case ADMIN_CONFIG_UPDATE_SUCCESS:
return importConfigs(state, ImmutableList(fromJS(action.configs)));
default:
return state;
}
}