2023-09-23 18:41:24 -07:00
|
|
|
import { produce } from 'immer';
|
2022-03-14 16:28:13 -07:00
|
|
|
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
2024-08-04 07:09:52 -07:00
|
|
|
import { type Instance, instanceSchema } from 'pl-api';
|
2022-03-14 16:28:13 -07:00
|
|
|
|
|
|
|
import { ADMIN_CONFIG_UPDATE_REQUEST, ADMIN_CONFIG_UPDATE_SUCCESS } from 'soapbox/actions/admin';
|
|
|
|
import { PLEROMA_PRELOAD_IMPORT } from 'soapbox/actions/preload';
|
2022-11-15 12:42:22 -08:00
|
|
|
import KVStore from 'soapbox/storage/kv-store';
|
2024-05-13 10:00:42 -07:00
|
|
|
import ConfigDB from 'soapbox/utils/config-db';
|
2022-03-14 16:28:13 -07:00
|
|
|
|
|
|
|
import {
|
2024-08-04 07:09:52 -07:00
|
|
|
INSTANCE_FETCH_FAIL,
|
|
|
|
INSTANCE_FETCH_SUCCESS,
|
2022-03-14 16:28:13 -07:00
|
|
|
} from '../actions/instance';
|
|
|
|
|
2022-06-09 12:08:51 -07:00
|
|
|
import type { AnyAction } from 'redux';
|
|
|
|
|
2023-09-23 18:41:24 -07:00
|
|
|
const initialState: Instance = instanceSchema.parse({});
|
2022-03-14 16:28:13 -07:00
|
|
|
|
2024-01-12 16:10:49 -08:00
|
|
|
const preloadImport = (state: Instance, action: Record<string, any>, path: string) => {
|
2022-03-14 16:28:13 -07:00
|
|
|
const instance = action.data[path];
|
2024-08-04 07:09:52 -07:00
|
|
|
return instance ? instanceSchema.parse(instance) : state;
|
2022-03-14 16:28:13 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2024-01-12 16:10:49 -08:00
|
|
|
const importConfigs = (state: Instance, configs: ImmutableList<any>) => {
|
2022-03-14 16:28:13 -07:00
|
|
|
// 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) => {
|
2022-03-14 16:28:13 -07:00
|
|
|
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;
|
2022-03-14 16:28:13 -07:00
|
|
|
|
2023-10-27 12:18:30 -07:00
|
|
|
draft.registrations = {
|
|
|
|
enabled: registrationsOpen ?? draft.registrations.enabled,
|
|
|
|
approval_required: approvalRequired ?? draft.registrations.approval_required,
|
|
|
|
};
|
2022-03-14 16:28:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (simplePolicy) {
|
2023-09-23 18:41:24 -07:00
|
|
|
draft.pleroma.metadata.federation.mrf_simple = simplePolicy;
|
2022-03-14 16:28:13 -07:00
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2024-01-12 16:10:49 -08:00
|
|
|
const handleAuthFetch = (state: Instance) => {
|
2022-03-14 16:28:13 -07:00
|
|
|
// 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 || '████████████',
|
|
|
|
};
|
2022-03-14 16:28:13 -07:00
|
|
|
};
|
|
|
|
|
2024-08-04 07:09:52 -07:00
|
|
|
const getHost = (instance: { domain: string }) => {
|
|
|
|
const domain = instance.domain;
|
2022-03-14 16:28:13 -07:00
|
|
|
try {
|
2024-04-09 15:03:18 -07:00
|
|
|
return new URL(domain).host;
|
2022-03-14 16:28:13 -07:00
|
|
|
} catch {
|
|
|
|
try {
|
2024-04-09 15:03:18 -07:00
|
|
|
return new URL(`https://${domain}`).host;
|
2022-03-14 16:28:13 -07:00
|
|
|
} catch {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-08-04 07:09:52 -07:00
|
|
|
const persistInstance = ({ instance }: { instance: { domain: string } }, host: string | null = getHost(instance)) => {
|
2022-03-14 16:28:13 -07:00
|
|
|
if (host) {
|
|
|
|
KVStore.setItem(`instance:${host}`, instance).catch(console.error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-01-12 16:10:49 -08:00
|
|
|
const handleInstanceFetchFail = (state: Instance, error: Record<string, any>) => {
|
2022-03-14 16:28:13 -07:00
|
|
|
if (error.response?.status === 401) {
|
|
|
|
return handleAuthFetch(state);
|
|
|
|
} else {
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-05-12 16:18:04 -07:00
|
|
|
const instance = (state = initialState, action: AnyAction) => {
|
2022-05-11 10:40:34 -07:00
|
|
|
switch (action.type) {
|
2022-05-11 14:06:35 -07:00
|
|
|
case PLEROMA_PRELOAD_IMPORT:
|
|
|
|
return preloadImport(state, action, '/api/v1/instance');
|
2024-08-04 07:09:52 -07:00
|
|
|
case INSTANCE_FETCH_SUCCESS:
|
|
|
|
persistInstance(action.instance);
|
|
|
|
return action.instance;
|
|
|
|
case INSTANCE_FETCH_FAIL:
|
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;
|
2022-03-14 16:28:13 -07:00
|
|
|
}
|
2024-05-12 16:18:04 -07:00
|
|
|
};
|
|
|
|
|
2024-05-13 10:00:42 -07:00
|
|
|
export { instance as default };
|