mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 04:55:42 +09:00
feat(limits): add max_screen_share_bitrate limit (#3410)
This commit is contained in:
1 parent
3292dc5f89
commit
e0640d68ff
9 files changed
+66
-6
No files matched your search
Generated
+2
-1
@@ -11107,7 +11107,7 @@
|
||||
"category": {"type": "string"},
|
||||
"scope": {"type": "string"},
|
||||
"isToggle": {"type": "boolean"},
|
||||
"unit": {"type": "string", "enum": ["bytes", "count"]},
|
||||
"unit": {"type": "string", "enum": ["bytes", "count", "bps"]},
|
||||
"min": {"type": "number"},
|
||||
"max": {"type": "number"}
|
||||
},
|
||||
@@ -11154,6 +11154,7 @@
|
||||
"max_private_channels_per_user",
|
||||
"max_reactions_per_message",
|
||||
"max_relationships",
|
||||
"max_screen_share_bitrate",
|
||||
"max_users_per_message_reaction",
|
||||
"max_voice_message_duration",
|
||||
"max_webhooks_per_channel",
|
||||
|
||||
@@ -12,6 +12,11 @@ pub fn limit_key_hint(key: &str) -> Option<Hint<'static>> {
|
||||
"Community creation policy",
|
||||
)),
|
||||
}),
|
||||
"max_screen_share_bitrate" => Some(Hint {
|
||||
name: Some("Max Screen Share Bitrate"),
|
||||
body: "In bits per second, so 9000000 is 9 Mbps. Raising it also raises the automatic bitrate of every screen share quality. Accounts with Higher Video Quality can pick their own bitrate up to this value.",
|
||||
link: None,
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ const CATEGORY_ORDER: &[&str] = &[
|
||||
"expressions",
|
||||
"files",
|
||||
"social",
|
||||
"media",
|
||||
];
|
||||
|
||||
pub fn limit_config_page(
|
||||
|
||||
@@ -8,7 +8,11 @@ import {HTTP_STATUS} from '@app/api/test/TestConstants';
|
||||
import {createBuilder} from '@app/api/test/TestRequestBuilder';
|
||||
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
|
||||
import {APIErrorCodes} from '@fluxer/constants/src/ApiErrorCodes';
|
||||
import {MAX_BIO_LENGTH} from '@fluxer/constants/src/LimitConstants';
|
||||
import {
|
||||
MAX_BIO_LENGTH,
|
||||
MAX_SCREEN_SHARE_BITRATE_CEILING,
|
||||
MIN_SCREEN_SHARE_BITRATE_CEILING,
|
||||
} from '@fluxer/constants/src/LimitConstants';
|
||||
import type {LimitConfigGetResponse} from '@fluxer/schema/src/domains/admin/AdminSchemas';
|
||||
import {afterAll, beforeAll, beforeEach, describe, expect, it} from 'vitest';
|
||||
import type {z} from 'zod';
|
||||
@@ -59,6 +63,30 @@ describe('limit config allowed ranges', () => {
|
||||
expect(saved.metadata.max_bio_length).toMatchObject({min: 0, max: MAX_BIO_LENGTH});
|
||||
});
|
||||
|
||||
it('keeps a screen share bitrate ceiling inside its allowed range', async () => {
|
||||
const admin = await createAdmin();
|
||||
const rule = (bitrate: number) => ({
|
||||
id: 'vip',
|
||||
filters: {traits: ['vip']},
|
||||
limits: {max_screen_share_bitrate: bitrate},
|
||||
});
|
||||
for (const bitrate of [MIN_SCREEN_SHARE_BITRATE_CEILING - 1, MAX_SCREEN_SHARE_BITRATE_CEILING + 1]) {
|
||||
await createBuilder(harness, admin.token)
|
||||
.put('/admin/limit-config')
|
||||
.body({limit_config: {traitDefinitions: ['vip'], rules: [rule(bitrate)]}})
|
||||
.expect(HTTP_STATUS.BAD_REQUEST, APIErrorCodes.INVALID_FORM_BODY)
|
||||
.execute();
|
||||
}
|
||||
const saved = await createBuilder<LimitConfigResponse>(harness, admin.token)
|
||||
.put('/admin/limit-config')
|
||||
.body({limit_config: {traitDefinitions: ['vip'], rules: [rule(25_000_000)]}})
|
||||
.execute();
|
||||
expect(saved.limit_config.rules.find((entry) => entry.id === 'vip')?.limits).toEqual({
|
||||
max_screen_share_bitrate: 25_000_000,
|
||||
});
|
||||
expect(saved.defaults.default?.max_screen_share_bitrate).toBe(9_000_000);
|
||||
});
|
||||
|
||||
it('reads a stored bio length above the profile maximum as the maximum', async () => {
|
||||
const admin = await createAdmin();
|
||||
await getInstanceConfigRepository().setLimitConfig({traitDefinitions: ['vip'], rules: [vipRule(1000)]});
|
||||
|
||||
@@ -385,6 +385,7 @@ Each key names one limit. A key whose name begins with `feature_` is a feature g
|
||||
| max_private_channels_per_user | Maximum direct message channels per user, in user scope |
|
||||
| max_reactions_per_message | Maximum distinct reactions per message, in guild scope |
|
||||
| max_relationships | Maximum friend and blocked relationships, in user scope |
|
||||
| max_screen_share_bitrate | Highest screen share video bitrate in bits per second, from 1000000 to 50000000, in user scope |
|
||||
| max_users_per_message_reaction | Maximum users who can use the same reaction on a message, in guild scope |
|
||||
| max_voice_message_duration | Maximum voice message duration in seconds, in user and guild scope |
|
||||
| max_webhooks_per_channel | Maximum webhooks per channel, in guild scope |
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {BASE64_IMAGE_MAX_SIZE, MAX_BIO_LENGTH} from '@fluxer/constants/src/LimitConstants';
|
||||
import {
|
||||
BASE64_IMAGE_MAX_SIZE,
|
||||
MAX_BIO_LENGTH,
|
||||
MAX_SCREEN_SHARE_BITRATE_CEILING,
|
||||
MIN_SCREEN_SHARE_BITRATE_CEILING,
|
||||
} from '@fluxer/constants/src/LimitConstants';
|
||||
|
||||
export const LIMIT_KEYS = [
|
||||
'avatar_max_size',
|
||||
@@ -42,6 +47,7 @@ export const LIMIT_KEYS = [
|
||||
'max_private_channels_per_user',
|
||||
'max_reactions_per_message',
|
||||
'max_relationships',
|
||||
'max_screen_share_bitrate',
|
||||
'max_users_per_message_reaction',
|
||||
'max_voice_message_duration',
|
||||
'max_webhooks_per_channel',
|
||||
@@ -92,6 +98,7 @@ export const LIMIT_KEY_SCOPES: Record<LimitKey, LimitScope> = {
|
||||
max_private_channels_per_user: 'user',
|
||||
max_reactions_per_message: 'guild',
|
||||
max_relationships: 'user',
|
||||
max_screen_share_bitrate: 'user',
|
||||
max_users_per_message_reaction: 'guild',
|
||||
max_voice_message_duration: 'both',
|
||||
max_webhooks_per_channel: 'guild',
|
||||
@@ -99,7 +106,7 @@ export const LIMIT_KEY_SCOPES: Record<LimitKey, LimitScope> = {
|
||||
sticker_max_size: 'guild',
|
||||
};
|
||||
|
||||
type LimitCategory = 'messages' | 'guilds' | 'channels' | 'expressions' | 'files' | 'social' | 'features';
|
||||
type LimitCategory = 'messages' | 'guilds' | 'channels' | 'expressions' | 'files' | 'social' | 'media' | 'features';
|
||||
|
||||
interface LimitKeyMetadata {
|
||||
key: LimitKey;
|
||||
@@ -108,7 +115,7 @@ interface LimitKeyMetadata {
|
||||
category: LimitCategory;
|
||||
scope: LimitScope;
|
||||
isToggle: boolean;
|
||||
unit?: 'bytes' | 'count';
|
||||
unit?: 'bytes' | 'count' | 'bps';
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
@@ -120,6 +127,7 @@ export const LIMIT_CATEGORY_LABELS: Record<LimitCategory, string> = {
|
||||
expressions: 'Expressions & Stickers',
|
||||
files: 'Files & Attachments',
|
||||
social: 'Social & Private',
|
||||
media: 'Voice & Video',
|
||||
features: 'Feature Toggles',
|
||||
};
|
||||
export const LIMIT_KEY_METADATA: Record<LimitKey, LimitKeyMetadata> = {
|
||||
@@ -437,6 +445,17 @@ export const LIMIT_KEY_METADATA: Record<LimitKey, LimitKeyMetadata> = {
|
||||
isToggle: false,
|
||||
unit: 'count',
|
||||
},
|
||||
max_screen_share_bitrate: {
|
||||
key: 'max_screen_share_bitrate',
|
||||
label: 'Max Screen Share Bitrate',
|
||||
description: 'Highest video bitrate a screen share can send, in bits per second',
|
||||
category: 'media',
|
||||
scope: 'user',
|
||||
isToggle: false,
|
||||
unit: 'bps',
|
||||
min: MIN_SCREEN_SHARE_BITRATE_CEILING,
|
||||
max: MAX_SCREEN_SHARE_BITRATE_CEILING,
|
||||
},
|
||||
feature_animated_avatar: {
|
||||
key: 'feature_animated_avatar',
|
||||
label: 'Animated Avatar',
|
||||
|
||||
@@ -72,6 +72,9 @@ export const MAX_FAVORITE_MEMES_NON_PREMIUM = 50;
|
||||
export const MAX_FAVORITE_MEME_TAGS = 10;
|
||||
export const MAX_FAVORITE_GIFS = 10000;
|
||||
export const MAX_VOICE_MESSAGE_DURATION = 1200;
|
||||
export const MAX_SCREEN_SHARE_BITRATE = 9_000_000;
|
||||
export const MIN_SCREEN_SHARE_BITRATE_CEILING = 1_000_000;
|
||||
export const MAX_SCREEN_SHARE_BITRATE_CEILING = 50_000_000;
|
||||
export const MAX_MEDIA_DURATION_SECONDS = 86400;
|
||||
export const EMOJI_MAX_SIZE = ASSET_FORMAT_POLICY.emoji.maxBytes;
|
||||
export const STICKER_MAX_SIZE = ASSET_FORMAT_POLICY.sticker.maxBytes;
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
MAX_PRIVATE_CHANNELS_PER_USER,
|
||||
MAX_REACTIONS_PER_MESSAGE,
|
||||
MAX_RELATIONSHIPS,
|
||||
MAX_SCREEN_SHARE_BITRATE,
|
||||
MAX_USERS_PER_MESSAGE_REACTION,
|
||||
MAX_VOICE_MESSAGE_DURATION,
|
||||
MAX_WEBHOOKS_PER_CHANNEL,
|
||||
@@ -80,6 +81,7 @@ export const DEFAULT_RESTRICTED_LIMITS: Record<LimitKey, number> = {
|
||||
max_private_channels_per_user: MAX_PRIVATE_CHANNELS_PER_USER,
|
||||
max_reactions_per_message: MAX_REACTIONS_PER_MESSAGE,
|
||||
max_relationships: MAX_RELATIONSHIPS,
|
||||
max_screen_share_bitrate: MAX_SCREEN_SHARE_BITRATE,
|
||||
max_users_per_message_reaction: MAX_USERS_PER_MESSAGE_REACTION,
|
||||
max_voice_message_duration: MAX_VOICE_MESSAGE_DURATION,
|
||||
max_webhooks_per_channel: MAX_WEBHOOKS_PER_CHANNEL,
|
||||
|
||||
@@ -1683,7 +1683,7 @@ const LimitKeyMetadataSchema = z.object({
|
||||
category: z.string(),
|
||||
scope: z.string(),
|
||||
isToggle: z.boolean(),
|
||||
unit: z.enum(['bytes', 'count']).optional(),
|
||||
unit: z.enum(['bytes', 'count', 'bps']).optional(),
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user