refactor: rename role.options -> role.policies

This commit is contained in:
syuilo
2023-01-15 20:52:53 +09:00
parent 518b3e2f73
commit 81f11d8f86
53 changed files with 254 additions and 232 deletions

View File

@ -479,8 +479,8 @@ export class DriveService {
if (user && !isLink) {
const usage = await this.driveFileEntityService.calcDriveUsageOf(user);
const role = await this.roleService.getUserRoleOptions(user.id);
const driveCapacity = 1024 * 1024 * role.driveCapacityMb;
const policies = await this.roleService.getUserPolicies(user.id);
const driveCapacity = 1024 * 1024 * policies.driveCapacityMb;
this.registerLogger.debug('drive capacity override applied');
this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`);

View File

@ -226,7 +226,7 @@ export class NoteCreateService {
if (data.channel != null) data.localOnly = true;
if (data.visibility === 'public' && data.channel == null) {
if ((await this.roleService.getUserRoleOptions(user.id)).canPublicNote === false) {
if ((await this.roleService.getUserPolicies(user.id)).canPublicNote === false) {
data.visibility = 'home';
}
}

View File

@ -57,7 +57,7 @@ export class NotePiningService {
const pinings = await this.userNotePiningsRepository.findBy({ userId: user.id });
if (pinings.length >= (await this.roleService.getUserRoleOptions(user.id)).pinLimit) {
if (pinings.length >= (await this.roleService.getUserPolicies(user.id)).pinLimit) {
throw new IdentifiableError('15a018eb-58e5-4da1-93be-330fcc5e4e1a', 'You can not pin notes any more.');
}

View File

@ -13,7 +13,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { StreamMessages } from '@/server/api/stream/types.js';
import type { OnApplicationShutdown } from '@nestjs/common';
export type RoleOptions = {
export type RolePolicies = {
gtlAvailable: boolean;
ltlAvailable: boolean;
canPublicNote: boolean;
@ -31,7 +31,7 @@ export type RoleOptions = {
rateLimitFactor: number;
};
export const DEFAULT_ROLE: RoleOptions = {
export const DEFAULT_POLICIES: RolePolicies = {
gtlAvailable: true,
ltlAvailable: true,
canPublicNote: true,
@ -195,26 +195,26 @@ export class RoleService implements OnApplicationShutdown {
}
@bindThis
public async getUserRoleOptions(userId: User['id'] | null): Promise<RoleOptions> {
public async getUserPolicies(userId: User['id'] | null): Promise<RolePolicies> {
const meta = await this.metaService.fetch();
const baseRoleOptions = { ...DEFAULT_ROLE, ...meta.defaultRoleOverride };
const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies };
if (userId == null) return baseRoleOptions;
if (userId == null) return basePolicies;
const roles = await this.getUserRoles(userId);
function calc<T extends keyof RoleOptions>(name: T, aggregate: (values: RoleOptions[T][]) => RoleOptions[T]) {
if (roles.length === 0) return baseRoleOptions[name];
function calc<T extends keyof RolePolicies>(name: T, aggregate: (values: RolePolicies[T][]) => RolePolicies[T]) {
if (roles.length === 0) return basePolicies[name];
const options = roles.map(role => role.options[name] ?? { priority: 0, useDefault: true });
const policies = roles.map(role => role.policies[name] ?? { priority: 0, useDefault: true });
const p2 = options.filter(option => option.priority === 2);
if (p2.length > 0) return aggregate(p2.map(option => option.useDefault ? baseRoleOptions[name] : option.value));
const p2 = policies.filter(policy => policy.priority === 2);
if (p2.length > 0) return aggregate(p2.map(policy => policy.useDefault ? basePolicies[name] : policy.value));
const p1 = options.filter(option => option.priority === 1);
if (p1.length > 0) return aggregate(p2.map(option => option.useDefault ? baseRoleOptions[name] : option.value));
const p1 = policies.filter(policy => policy.priority === 1);
if (p1.length > 0) return aggregate(p2.map(policy => policy.useDefault ? basePolicies[name] : policy.value));
return aggregate(options.map(option => option.useDefault ? baseRoleOptions[name] : option.value));
return aggregate(policies.map(policy => policy.useDefault ? basePolicies[name] : policy.value));
}
return {

View File

@ -35,7 +35,7 @@ export class UserListService {
const currentCount = await this.userListJoiningsRepository.countBy({
userListId: list.id,
});
if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).userEachUserListsLimit) {
if (currentCount > (await this.roleService.getUserPolicies(me.id)).userEachUserListsLimit) {
throw new Error('Too many users');
}

View File

@ -6,7 +6,7 @@ import type { Packed } from '@/misc/schema.js';
import type { User } from '@/models/entities/User.js';
import type { Role } from '@/models/entities/Role.js';
import { bindThis } from '@/decorators.js';
import { DEFAULT_ROLE } from '@/core/RoleService.js';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
import { UserEntityService } from './UserEntityService.js';
@Injectable()
@ -40,9 +40,9 @@ export class RoleEntityService {
roleId: role.id,
});
const roleOptions = { ...role.options };
for (const [k, v] of Object.entries(DEFAULT_ROLE)) {
if (roleOptions[k] == null) roleOptions[k] = {
const policies = { ...role.policies };
for (const [k, v] of Object.entries(DEFAULT_POLICIES)) {
if (policies[k] == null) policies[k] = {
useDefault: true,
priority: 0,
value: v,
@ -62,7 +62,7 @@ export class RoleEntityService {
isAdministrator: role.isAdministrator,
isModerator: role.isModerator,
canEditMembersByModerator: role.canEditMembersByModerator,
options: roleOptions,
policies: policies,
usersCount: assigns.length,
...(opts.detail ? {
users: this.userEntityService.packMany(assigns.map(x => x.userId), me),

View File

@ -423,7 +423,7 @@ export class UserEntityService implements OnModuleInit {
bannerUrl: user.banner ? this.driveFileEntityService.getPublicUrl(user.banner, false) : null,
bannerBlurhash: user.banner?.blurhash ?? null,
isLocked: user.isLocked,
isSilenced: this.roleService.getUserRoleOptions(user.id).then(r => !r.canPublicNote),
isSilenced: this.roleService.getUserPolicies(user.id).then(r => !r.canPublicNote),
isSuspended: user.isSuspended ?? falsy,
description: profile!.description,
location: profile!.location,
@ -496,7 +496,7 @@ export class UserEntityService implements OnModuleInit {
} : {}),
...(opts.includeSecrets ? {
role: this.roleService.getUserRoleOptions(user.id),
policies: this.roleService.getUserPolicies(user.id),
email: profile!.email,
emailVerified: profile!.emailVerified,
securityKeysList: profile!.twoFactorEnabled

View File

@ -458,5 +458,5 @@ export class Meta {
@Column('jsonb', {
default: { },
})
public defaultRoleOverride: Record<string, any>;
public policies: Record<string, any>;
}

View File

@ -136,7 +136,7 @@ export class Role {
@Column('jsonb', {
default: { },
})
public options: Record<string, {
public policies: Record<string, {
useDefault: boolean;
priority: number;
value: any;

View File

@ -10,7 +10,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { bindThis } from '@/decorators.js';
import NotesChart from '@/core/chart/charts/notes.js';
import UsersChart from '@/core/chart/charts/users.js';
import { DEFAULT_ROLE } from '@/core/RoleService.js';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
const nodeinfo2_1path = '/nodeinfo/2.1';
@ -74,7 +74,7 @@ export class NodeinfoServerService {
const proxyAccount = meta.proxyAccountId ? await this.userEntityService.pack(meta.proxyAccountId).catch(() => null) : null;
const baseRoleOptions = { ...DEFAULT_ROLE, ...meta.defaultRoleOverride };
const basePolicies = { ...DEFAULT_POLICIES, ...meta.policies };
return {
software: {
@ -105,8 +105,8 @@ export class NodeinfoServerService {
repositoryUrl: meta.repositoryUrl,
feedbackUrl: meta.feedbackUrl,
disableRegistration: meta.disableRegistration,
disableLocalTimeline: !baseRoleOptions.ltlAvailable,
disableGlobalTimeline: !baseRoleOptions.gtlAvailable,
disableLocalTimeline: !basePolicies.ltlAvailable,
disableGlobalTimeline: !basePolicies.gtlAvailable,
emailRequiredForSignup: meta.emailRequiredForSignup,
enableHcaptcha: meta.enableHcaptcha,
enableRecaptcha: meta.enableRecaptcha,

View File

@ -225,7 +225,7 @@ export class ApiCallService implements OnApplicationShutdown {
}
// TODO: 毎リクエスト計算するのもあれだしキャッシュしたい
const factor = user ? (await this.roleService.getUserRoleOptions(user.id)).rateLimitFactor : 1;
const factor = user ? (await this.roleService.getUserPolicies(user.id)).rateLimitFactor : 1;
// Rate limit
await this.rateLimiterService.limit(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor, factor).catch(err => {
@ -274,9 +274,9 @@ export class ApiCallService implements OnApplicationShutdown {
}
}
if (ep.meta.requireRoleOption != null && !user!.isRoot) {
const myRole = await this.roleService.getUserRoleOptions(user!.id);
if (!myRole[ep.meta.requireRoleOption]) {
if (ep.meta.requireRolePolicy != null && !user!.isRoot) {
const policies = await this.roleService.getUserPolicies(user!.id);
if (!policies[ep.meta.requireRolePolicy]) {
throw new ApiError({
message: 'You are not assigned to a required role.',
code: 'ROLE_PERMISSION_DENIED',

View File

@ -65,7 +65,7 @@ import * as ep___admin_roles_show from './endpoints/admin/roles/show.js';
import * as ep___admin_roles_update from './endpoints/admin/roles/update.js';
import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js';
import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js';
import * as ep___admin_roles_updateDefaultRoleOverride from './endpoints/admin/roles/update-default-role-override.js';
import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js';
import * as ep___announcements from './endpoints/announcements.js';
import * as ep___antennas_create from './endpoints/antennas/create.js';
import * as ep___antennas_delete from './endpoints/antennas/delete.js';
@ -399,7 +399,7 @@ const $admin_roles_show: Provider = { provide: 'ep:admin/roles/show', useClass:
const $admin_roles_update: Provider = { provide: 'ep:admin/roles/update', useClass: ep___admin_roles_update.default };
const $admin_roles_assign: Provider = { provide: 'ep:admin/roles/assign', useClass: ep___admin_roles_assign.default };
const $admin_roles_unassign: Provider = { provide: 'ep:admin/roles/unassign', useClass: ep___admin_roles_unassign.default };
const $admin_roles_updateDefaultRoleOverride: Provider = { provide: 'ep:admin/roles/update-default-role-override', useClass: ep___admin_roles_updateDefaultRoleOverride.default };
const $admin_roles_updateDefaultPolicies: Provider = { provide: 'ep:admin/roles/update-default-policies', useClass: ep___admin_roles_updateDefaultPolicies.default };
const $announcements: Provider = { provide: 'ep:announcements', useClass: ep___announcements.default };
const $antennas_create: Provider = { provide: 'ep:antennas/create', useClass: ep___antennas_create.default };
const $antennas_delete: Provider = { provide: 'ep:antennas/delete', useClass: ep___antennas_delete.default };
@ -737,7 +737,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$admin_roles_update,
$admin_roles_assign,
$admin_roles_unassign,
$admin_roles_updateDefaultRoleOverride,
$admin_roles_updateDefaultPolicies,
$announcements,
$antennas_create,
$antennas_delete,
@ -1069,7 +1069,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
$admin_roles_update,
$admin_roles_assign,
$admin_roles_unassign,
$admin_roles_updateDefaultRoleOverride,
$admin_roles_updateDefaultPolicies,
$announcements,
$antennas_create,
$antennas_delete,

View File

@ -64,7 +64,7 @@ import * as ep___admin_roles_show from './endpoints/admin/roles/show.js';
import * as ep___admin_roles_update from './endpoints/admin/roles/update.js';
import * as ep___admin_roles_assign from './endpoints/admin/roles/assign.js';
import * as ep___admin_roles_unassign from './endpoints/admin/roles/unassign.js';
import * as ep___admin_roles_updateDefaultRoleOverride from './endpoints/admin/roles/update-default-role-override.js';
import * as ep___admin_roles_updateDefaultPolicies from './endpoints/admin/roles/update-default-policies.js';
import * as ep___announcements from './endpoints/announcements.js';
import * as ep___antennas_create from './endpoints/antennas/create.js';
import * as ep___antennas_delete from './endpoints/antennas/delete.js';
@ -396,7 +396,7 @@ const eps = [
['admin/roles/update', ep___admin_roles_update],
['admin/roles/assign', ep___admin_roles_assign],
['admin/roles/unassign', ep___admin_roles_unassign],
['admin/roles/update-default-role-override', ep___admin_roles_updateDefaultRoleOverride],
['admin/roles/update-default-policies', ep___admin_roles_updateDefaultPolicies],
['announcements', ep___announcements],
['antennas/create', ep___antennas_create],
['antennas/delete', ep___antennas_delete],
@ -695,7 +695,7 @@ export interface IEndpointMeta {
*/
readonly requireAdmin?: boolean;
readonly requireRoleOption?: string;
readonly requireRolePolicy?: string;
/**
* エンドポイントのリミテーションに関するやつ

View File

@ -8,7 +8,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
} as const;
export const paramDef = {

View File

@ -14,7 +14,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
errors: {
noSuchFile: {

View File

@ -14,7 +14,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
errors: {
noSuchEmoji: {

View File

@ -9,7 +9,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
} as const;
export const paramDef = {

View File

@ -10,7 +10,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
errors: {
noSuchEmoji: {

View File

@ -5,7 +5,7 @@ import { QueueService } from '@/core/QueueService.js';
export const meta = {
secure: true,
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
} as const;
export const paramDef = {

View File

@ -11,7 +11,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
res: {
type: 'array',

View File

@ -11,7 +11,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
res: {
type: 'array',

View File

@ -8,7 +8,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
} as const;
export const paramDef = {

View File

@ -8,7 +8,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
} as const;
export const paramDef = {

View File

@ -8,7 +8,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
} as const;
export const paramDef = {

View File

@ -9,7 +9,7 @@ export const meta = {
tags: ['admin'],
requireCredential: true,
requireRoleOption: 'canManageCustomEmojis',
requireRolePolicy: 'canManageCustomEmojis',
errors: {
noSuchEmoji: {

View File

@ -4,7 +4,7 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import { MetaService } from '@/core/MetaService.js';
import type { Config } from '@/config.js';
import { DI } from '@/di-symbols.js';
import { DEFAULT_ROLE } from '@/core/RoleService.js';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
export const meta = {
tags: ['meta'],
@ -440,7 +440,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
deeplIsPro: instance.deeplIsPro,
enableIpLogging: instance.enableIpLogging,
enableActiveEmailValidation: instance.enableActiveEmailValidation,
baseRole: { ...DEFAULT_ROLE, ...instance.defaultRoleOverride },
policies: { ...DEFAULT_POLICIES, ...instance.policies },
};
});
}

View File

@ -25,7 +25,7 @@ export const paramDef = {
isModerator: { type: 'boolean' },
isAdministrator: { type: 'boolean' },
canEditMembersByModerator: { type: 'boolean' },
options: {
policies: {
type: 'object',
},
},
@ -39,7 +39,7 @@ export const paramDef = {
'isModerator',
'isAdministrator',
'canEditMembersByModerator',
'options',
'policies',
],
} as const;
@ -70,7 +70,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
isAdministrator: ps.isAdministrator,
isModerator: ps.isModerator,
canEditMembersByModerator: ps.canEditMembersByModerator,
options: ps.options,
policies: ps.policies,
}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0]));
this.globalEventService.publishInternalEvent('roleCreated', created);

View File

@ -16,12 +16,12 @@ export const meta = {
export const paramDef = {
type: 'object',
properties: {
options: {
policies: {
type: 'object',
},
},
required: [
'options',
'policies',
],
} as const;
@ -34,9 +34,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
) {
super(meta, paramDef, async (ps) => {
await this.metaService.update({
defaultRoleOverride: ps.options,
policies: ps.policies,
});
this.globalEventService.publishInternalEvent('defaultRoleOverrideUpdated', ps.options);
this.globalEventService.publishInternalEvent('policiesUpdated', ps.policies);
});
}
}

View File

@ -33,7 +33,7 @@ export const paramDef = {
isModerator: { type: 'boolean' },
isAdministrator: { type: 'boolean' },
canEditMembersByModerator: { type: 'boolean' },
options: {
policies: {
type: 'object',
},
},
@ -48,7 +48,7 @@ export const paramDef = {
'isModerator',
'isAdministrator',
'canEditMembersByModerator',
'options',
'policies',
],
} as const;
@ -79,7 +79,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
isModerator: ps.isModerator,
isAdministrator: ps.isAdministrator,
canEditMembersByModerator: ps.canEditMembersByModerator,
options: ps.options,
policies: ps.policies,
});
const updated = await this.rolesRepository.findOneByOrFail({ id: ps.roleId });
this.globalEventService.publishInternalEvent('roleUpdated', updated);

View File

@ -52,7 +52,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}
const isModerator = await this.roleService.isModerator(user);
const isSilenced = !(await this.roleService.getUserRoleOptions(user.id)).canPublicNote;
const isSilenced = !(await this.roleService.getUserPolicies(user.id)).canPublicNote;
const _me = await this.usersRepository.findOneByOrFail({ id: me.id });
if (!await this.roleService.isAdministrator(_me) && await this.roleService.isAdministrator(user)) {
@ -94,6 +94,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
lastActiveDate: user.lastActiveDate,
moderationNote: profile.moderationNote,
signins,
policies: await this.roleService.getUserPolicies(user.id),
roles: await this.roleEntityService.packMany(roles, me, { detail: false }),
};
});

View File

@ -92,7 +92,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const currentAntennasCount = await this.antennasRepository.countBy({
userId: me.id,
});
if (currentAntennasCount > (await this.roleService.getUserRoleOptions(me.id)).antennaLimit) {
if (currentAntennasCount > (await this.roleService.getUserPolicies(me.id)).antennaLimit) {
throw new ApiError(meta.errors.tooManyAntennas);
}

View File

@ -97,7 +97,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const currentCount = await this.clipNotesRepository.countBy({
clipId: clip.id,
});
if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).noteEachClipsLimit) {
if (currentCount > (await this.roleService.getUserPolicies(me.id)).noteEachClipsLimit) {
throw new ApiError(meta.errors.tooManyClipNotes);
}

View File

@ -54,7 +54,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const currentCount = await this.clipsRepository.countBy({
userId: me.id,
});
if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).clipLimit) {
if (currentCount > (await this.roleService.getUserPolicies(me.id)).clipLimit) {
throw new ApiError(meta.errors.tooManyClips);
}

View File

@ -47,10 +47,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
// Calculate drive usage
const usage = await this.driveFileEntityService.calcDriveUsageOf(me.id);
const myRole = await this.roleService.getUserRoleOptions(me.id);
const policies = await this.roleService.getUserPolicies(me.id);
return {
capacity: 1024 * 1024 * myRole.driveCapacityMb,
capacity: 1024 * 1024 * policies.driveCapacityMb,
usage: usage,
};
});

View File

@ -173,7 +173,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (ps.mutedWords !== undefined) {
// TODO: ちゃんと数える
const length = JSON.stringify(ps.mutedWords).length;
if (length > (await this.roleService.getUserRoleOptions(user.id)).wordMuteLimit) {
if (length > (await this.roleService.getUserPolicies(user.id)).wordMuteLimit) {
throw new ApiError(meta.errors.tooManyMutedWords);
}

View File

@ -54,7 +54,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const currentWebhooksCount = await this.webhooksRepository.countBy({
userId: me.id,
});
if (currentWebhooksCount > (await this.roleService.getUserRoleOptions(me.id)).webhookLimit) {
if (currentWebhooksCount > (await this.roleService.getUserPolicies(me.id)).webhookLimit) {
throw new ApiError(meta.errors.tooManyWebhooks);
}

View File

@ -9,7 +9,7 @@ export const meta = {
tags: ['meta'],
requireCredential: true,
requireRoleOption: 'canInvite',
requireRolePolicy: 'canInvite',
res: {
type: 'object',

View File

@ -7,7 +7,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { MetaService } from '@/core/MetaService.js';
import type { Config } from '@/config.js';
import { DI } from '@/di-symbols.js';
import { DEFAULT_ROLE } from '@/core/RoleService.js';
import { DEFAULT_POLICIES } from '@/core/RoleService.js';
export const meta = {
tags: ['meta'],
@ -334,7 +334,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
translatorAvailable: instance.deeplAuthKey != null,
baseRole: { ...DEFAULT_ROLE, ...instance.defaultRoleOverride },
policies: { ...DEFAULT_POLICIES, ...instance.policies },
...(ps.detail ? {
pinnedPages: instance.pinnedPages,

View File

@ -62,8 +62,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private activeUsersChart: ActiveUsersChart,
) {
super(meta, paramDef, async (ps, me) => {
const role = await this.roleService.getUserRoleOptions(me ? me.id : null);
if (!role.gtlAvailable) {
const policies = await this.roleService.getUserPolicies(me ? me.id : null);
if (!policies.gtlAvailable) {
throw new ApiError(meta.errors.gtlDisabled);
}

View File

@ -71,8 +71,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private activeUsersChart: ActiveUsersChart,
) {
super(meta, paramDef, async (ps, me) => {
const role = await this.roleService.getUserRoleOptions(me.id);
if (!role.ltlAvailable) {
const policies = await this.roleService.getUserPolicies(me.id);
if (!policies.ltlAvailable) {
throw new ApiError(meta.errors.stlDisabled);
}

View File

@ -67,8 +67,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private activeUsersChart: ActiveUsersChart,
) {
super(meta, paramDef, async (ps, me) => {
const role = await this.roleService.getUserRoleOptions(me ? me.id : null);
if (!role.ltlAvailable) {
const policies = await this.roleService.getUserPolicies(me ? me.id : null);
if (!policies.ltlAvailable) {
throw new ApiError(meta.errors.ltlDisabled);
}

View File

@ -55,7 +55,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
const currentCount = await this.userListsRepository.countBy({
userId: me.id,
});
if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).userListLimit) {
if (currentCount > (await this.roleService.getUserPolicies(me.id)).userListLimit) {
throw new ApiError(meta.errors.tooManyUserLists);
}

View File

@ -29,8 +29,8 @@ class GlobalTimelineChannel extends Channel {
@bindThis
public async init(params: any) {
const role = await this.roleService.getUserRoleOptions(this.user ? this.user.id : null);
if (!role.gtlAvailable) return;
const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
if (!policies.gtlAvailable) return;
// Subscribe events
this.subscriber.on('notesStream', this.onNote);

View File

@ -30,8 +30,8 @@ class HybridTimelineChannel extends Channel {
@bindThis
public async init(params: any): Promise<void> {
const role = await this.roleService.getUserRoleOptions(this.user ? this.user.id : null);
if (!role.ltlAvailable) return;
const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
if (!policies.ltlAvailable) return;
// Subscribe events
this.subscriber.on('notesStream', this.onNote);

View File

@ -28,8 +28,8 @@ class LocalTimelineChannel extends Channel {
@bindThis
public async init(params: any) {
const role = await this.roleService.getUserRoleOptions(this.user ? this.user.id : null);
if (!role.ltlAvailable) return;
const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
if (!policies.ltlAvailable) return;
// Subscribe events
this.subscriber.on('notesStream', this.onNote);

View File

@ -30,7 +30,7 @@ export interface InternalStreamTypes {
remoteUserUpdated: Serialized<{ id: User['id']; }>;
follow: Serialized<{ followerId: User['id']; followeeId: User['id']; }>;
unfollow: Serialized<{ followerId: User['id']; followeeId: User['id']; }>;
defaultRoleOverrideUpdated: Serialized<Role['options']>;
policiesUpdated: Serialized<Role['options']>;
roleCreated: Serialized<Role>;
roleDeleted: Serialized<Role>;
roleUpdated: Serialized<Role>;