This commit is contained in:
2026-07-19 19:27:02 +02:00
parent 23998b9ea9
commit 62f7c6edba
9 changed files with 1080 additions and 151 deletions
-103
View File
@@ -1,103 +0,0 @@
<template>
<v-container class="fill-height d-flex flex-column justify-center" max-width="1100">
<div>
<v-img
class="mb-4 font-weight-bold"
height="150"
src="@/assets/logo.png"
/>
<div class="mb-8 text-center">
<div class="text-body-medium font-weight-light mb-n1">Welcome to</div>
<div class="text-display-medium font-weight-bold">Vuetify</div>
</div>
<v-row>
<v-col cols="12">
<v-card
class="py-4"
color="surface-variant"
image="https://cdn.vuetifyjs.com/docs/images/one/create/feature.png"
rounded="lg"
variant="tonal"
>
<template #prepend>
<v-avatar class="ml-2 mr-4" icon="mdi-rocket-launch-outline" size="60" variant="tonal"/>
</template>
<template #image>
<v-img position="top right"/>
</template>
<template #title>
<div class="my-title my-uppercase text-headline-medium font-weight-bold">Get started</div>
</template>
<template #subtitle>
<div class="text-body-large">
Change this page by updating
<v-kbd>{{
`
<HelloWorld/>
` }}
</v-kbd>
in
<v-kbd>components/HelloWorld.vue</v-kbd>
.
</div>
</template>
</v-card>
</v-col>
<v-col v-for="link in links" :key="link.href" cols="6">
<v-card
:href="link.href"
:subtitle="link.subtitle"
:title="link.title"
append-icon="mdi-open-in-new"
class="py-4"
color="surface-variant"
rel="noopener noreferrer"
rounded="lg"
target="_blank"
variant="tonal"
>
<template #prepend>
<v-avatar :icon="link.icon" class="ml-2 mr-4" size="60" variant="tonal"/>
</template>
</v-card>
</v-col>
</v-row>
</div>
</v-container>
</template>
<script lang="ts" setup>
const links = [
{
href: 'https://vuetifyjs.com/',
icon: 'mdi-text-box-outline',
subtitle: 'Learn about all things Vuetify in our documentation.',
title: 'Documentation',
},
{
href: 'https://vuetifyjs.com/introduction/why-vuetify/#feature-guides',
icon: 'mdi-star-circle-outline',
subtitle: 'Explore available framework Features.',
title: 'Features',
},
{
href: 'https://vuetifyjs.com/components/all',
icon: 'mdi-widgets-outline',
subtitle: 'Discover components in the API Explorer.',
title: 'Components',
},
{
href: 'https://discord.vuetifyjs.com',
icon: 'mdi-account-group-outline',
subtitle: 'Connect with Vuetify developers.',
title: 'Community',
},
]
</script>
-35
View File
@@ -1,35 +0,0 @@
# Components
Vue template files in this folder are automatically imported.
## 🚀 Usage
Importing is handled by [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components). This plugin automatically imports `.vue` files created in the `src/components` directory, and registers them as global components. This means that you can use any component in your application without having to manually import it.
The following example assumes a component located at `src/components/MyComponent.vue`:
```vue
<template>
<div>
<MyComponent />
</div>
</template>
<script lang="ts" setup>
//
</script>
```
When your template is rendered, the component's import will automatically be inlined, which renders to this:
```vue
<template>
<div>
<MyComponent />
</div>
</template>
<script lang="ts" setup>
import MyComponent from '@/components/MyComponent.vue'
</script>
```
@@ -0,0 +1,181 @@
<!--
Exemple d'utilisation :
<script lang="ts" setup>
import { ref } from 'vue'
import ChannelPermissionEditor from '@/components/permissions/ChannelPermissionEditor.vue'
import {
toChannelPermissionMask,
type ChannelPermissionMask,
} from '@/types/permissions'
const permissions = ref<ChannelPermissionMask>(
toChannelPermissionMask(0),
)
function saveChannelPermissions(
value: ChannelPermissionMask,
) {
permissions.value = value
// Appel usePermissions().setChannelRolePermission(...)
}
</script>
<template>
<ChannelPermissionEditor
v-model="permissions"
@save="saveChannelPermissions"
/>
</template>
-->
<script lang="ts" setup>
import {computed, ref, watch} from 'vue'
import {
CHANNEL_PERMISSION_DEFINITIONS,
type ChannelPermissionMask,
grantChannelPermission,
revokeChannelPermission,
} from '@/types/permissions'
const props = withDefaults(defineProps<{
modelValue: ChannelPermissionMask
loading?: boolean
readonly?: boolean
title?: string
}>(), {
loading: false,
readonly: false,
title: 'Permissions du canal',
})
const emit = defineEmits<{
'update:modelValue': [permissions: ChannelPermissionMask]
save: [permissions: ChannelPermissionMask]
}>()
const permissions = ref<ChannelPermissionMask>(props.modelValue)
watch(
() => props.modelValue,
(value) => {
permissions.value = value
},
)
const permissionGroups = computed(() => {
const groups = new Map<
string,
typeof CHANNEL_PERMISSION_DEFINITIONS
>()
for (const permission of CHANNEL_PERMISSION_DEFINITIONS) {
const group = groups.get(permission.category) ?? []
group.push(permission)
groups.set(permission.category, group)
}
const labels: Record<string, string> = {
chat: 'Discussion',
management: 'Gestion',
voice: 'Vocal',
}
return Array.from(groups.entries()).map(([key, items]) => ({
key,
label: labels[key] ?? key,
permissions: items,
}))
})
function isEnabled(bit: ChannelPermissionMask): boolean {
return (permissions.value & bit) === bit
}
function updatePermission(
bit: ChannelPermissionMask,
enabled: boolean,
): void {
if (props.readonly || props.loading) {
return
}
permissions.value = enabled
? grantChannelPermission(permissions.value, bit)
: revokeChannelPermission(permissions.value, bit)
emit('update:modelValue', permissions.value)
}
function save(): void {
if (props.readonly || props.loading) {
return
}
emit('save', permissions.value)
}
</script>
<template>
<v-card>
<v-card-title>{{ title }}</v-card-title>
<v-divider/>
<v-card-text>
<v-expansion-panels multiple>
<v-expansion-panel
v-for="group in permissionGroups"
:key="group.key"
:title="group.label"
>
<v-expansion-panel-text>
<v-list lines="two">
<v-list-item
v-for="permission in group.permissions"
:key="permission.key"
class="px-0"
>
<template #prepend>
<v-checkbox
:disabled="readonly || loading"
:model-value="isEnabled(permission.bit)"
color="primary"
hide-details
@update:model-value="
updatePermission(permission.bit, Boolean($event))
"
/>
</template>
<v-list-item-title>
{{ permission.label }}
</v-list-item-title>
<v-list-item-subtitle
v-if="permission.description"
>
{{ permission.description }}
</v-list-item-subtitle>
</v-list-item>
</v-list>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card-text>
<v-divider/>
<v-card-actions>
<v-spacer/>
<v-btn
:disabled="readonly || loading"
:loading="loading"
color="primary"
@click="save"
>
Enregistrer
</v-btn>
</v-card-actions>
</v-card>
</template>
@@ -0,0 +1,175 @@
<!--
Exemple d'utilisation :
<script lang="ts" setup>
import { ref } from 'vue'
import ServerPermissionEditor from '@/components/permissions/ServerPermissionEditor.vue'
import {
toServerPermissionMask,
type ServerPermissionMask,
} from '@/types/permissions'
const permissions = ref<ServerPermissionMask>(
toServerPermissionMask(0),
)
function saveServerPermissions(
value: ServerPermissionMask,
) {
permissions.value = value
// Appel usePermissions().setServerRolePermission(...)
}
</script>
<template>
<ServerPermissionEditor
v-model="permissions"
@save="saveServerPermissions"
/>
</template>
-->
<script lang="ts" setup>
import {computed, ref, watch} from 'vue'
import {
grantServerPermission,
revokeServerPermission,
SERVER_PERMISSION_DEFINITIONS,
type ServerPermissionMask,
} from '@/types/permissions'
const props = withDefaults(defineProps<{
modelValue: ServerPermissionMask
loading?: boolean
readonly?: boolean
title?: string
}>(), {
loading: false,
readonly: false,
title: 'Permissions du serveur',
})
const emit = defineEmits<{
'update:modelValue': [permissions: ServerPermissionMask]
save: [permissions: ServerPermissionMask]
}>()
const permissions = ref<ServerPermissionMask>(props.modelValue)
watch(
() => props.modelValue,
(value) => {
permissions.value = value
},
)
const permissionGroups = computed(() => {
const groups = new Map<
string,
typeof SERVER_PERMISSION_DEFINITIONS
>()
for (const permission of SERVER_PERMISSION_DEFINITIONS) {
const group = groups.get(permission.category) ?? []
group.push(permission)
groups.set(permission.category, group)
}
return Array.from(groups.entries()).map(([key, items]) => ({
key,
label: key === 'management' ? 'Gestion' : 'Membres',
permissions: items,
}))
})
function isEnabled(bit: ServerPermissionMask): boolean {
return (permissions.value & bit) === bit
}
function updatePermission(
bit: ServerPermissionMask,
enabled: boolean,
): void {
if (props.readonly || props.loading) {
return
}
permissions.value = enabled
? grantServerPermission(permissions.value, bit)
: revokeServerPermission(permissions.value, bit)
emit('update:modelValue', permissions.value)
}
function save(): void {
if (props.readonly || props.loading) {
return
}
emit('save', permissions.value)
}
</script>
<template>
<v-card>
<v-card-title>{{ title }}</v-card-title>
<v-divider/>
<v-card-text>
<v-expansion-panels multiple>
<v-expansion-panel
v-for="group in permissionGroups"
:key="group.key"
:title="group.label"
>
<v-expansion-panel-text>
<v-list lines="two">
<v-list-item
v-for="permission in group.permissions"
:key="permission.key"
class="px-0"
>
<template #prepend>
<v-checkbox
:disabled="readonly || loading"
:model-value="isEnabled(permission.bit)"
color="primary"
hide-details
@update:model-value="
updatePermission(permission.bit, Boolean($event))
"
/>
</template>
<v-list-item-title>
{{ permission.label }}
</v-list-item-title>
<v-list-item-subtitle
v-if="permission.description"
>
{{ permission.description }}
</v-list-item-subtitle>
</v-list-item>
</v-list>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card-text>
<v-divider/>
<v-card-actions>
<v-spacer/>
<v-btn
:disabled="readonly || loading"
:loading="loading"
color="primary"
@click="save"
>
Enregistrer
</v-btn>
</v-card-actions>
</v-card>
</template>
+235
View File
@@ -0,0 +1,235 @@
import {useApi} from '@/composables/useApi'
import {
type ChannelRolePermission,
type ChannelRolePermissionDto,
channelRolePermissionFromDto,
type ChannelUserPermission,
type ChannelUserPermissionDto,
channelUserPermissionFromDto,
type PermissionMaskInput,
permissionMaskToJson,
type ServerRolePermission,
type ServerRolePermissionDto,
serverRolePermissionFromDto,
type ServerUserPermission,
type ServerUserPermissionDto,
serverUserPermissionFromDto,
} from '@/types/permissions'
export function usePermissions() {
const api = useApi()
async function parseResponse<T>(response: Response): Promise<T> {
if (!response.ok) {
const error = await response.json().catch(() => null)
throw new Error(
error?.message || 'Erreur lors de la gestion des permissions',
)
}
if (response.status === 204) {
return undefined as T
}
return response.json() as Promise<T>
}
// ---------------------------------------------------------------------------
// Permissions serveur - utilisateur
// ---------------------------------------------------------------------------
async function getServerUserPermission(
serverId: string,
userId: string,
): Promise<ServerUserPermission> {
const response = await api.get(
`/servers/${serverId}/permissions/users/${userId}`,
)
const dto = await parseResponse<ServerUserPermissionDto>(response)
return serverUserPermissionFromDto(dto)
}
async function setServerUserPermission(
serverId: string,
userId: string,
permissions: PermissionMaskInput,
): Promise<ServerUserPermission> {
const response = await api.put(
`/servers/${serverId}/permissions/users/${userId}`,
{
permissions: permissionMaskToJson(permissions),
},
)
const dto = await parseResponse<ServerUserPermissionDto>(response)
return serverUserPermissionFromDto(dto)
}
async function removeServerUserPermission(
serverId: string,
userId: string,
): Promise<void> {
const response = await api.delete(
`/servers/${serverId}/permissions/users/${userId}`,
)
await parseResponse<void>(response)
}
// ---------------------------------------------------------------------------
// Permissions serveur - rôle
// ---------------------------------------------------------------------------
async function getServerRolePermission(
serverId: string,
roleId: string,
): Promise<ServerRolePermission> {
const response = await api.get(
`/servers/${serverId}/permissions/roles/${roleId}`,
)
const dto = await parseResponse<ServerRolePermissionDto>(response)
return serverRolePermissionFromDto(dto)
}
async function setServerRolePermission(
serverId: string,
roleId: string,
permissions: PermissionMaskInput,
): Promise<ServerRolePermission> {
const response = await api.put(
`/servers/${serverId}/permissions/roles/${roleId}`,
{
permissions: permissionMaskToJson(permissions),
},
)
const dto = await parseResponse<ServerRolePermissionDto>(response)
return serverRolePermissionFromDto(dto)
}
async function removeServerRolePermission(
serverId: string,
roleId: string,
): Promise<void> {
const response = await api.delete(
`/servers/${serverId}/permissions/roles/${roleId}`,
)
await parseResponse<void>(response)
}
// ---------------------------------------------------------------------------
// Permissions canal - utilisateur
// ---------------------------------------------------------------------------
async function getChannelUserPermission(
channelId: string,
userId: string,
): Promise<ChannelUserPermission> {
const response = await api.get(
`/channels/${channelId}/permissions/users/${userId}`,
)
const dto = await parseResponse<ChannelUserPermissionDto>(response)
return channelUserPermissionFromDto(dto)
}
async function setChannelUserPermission(
channelId: string,
userId: string,
permissions: PermissionMaskInput,
): Promise<ChannelUserPermission> {
const response = await api.put(
`/channels/${channelId}/permissions/users/${userId}`,
{
permissions: permissionMaskToJson(permissions),
},
)
const dto = await parseResponse<ChannelUserPermissionDto>(response)
return channelUserPermissionFromDto(dto)
}
async function removeChannelUserPermission(
channelId: string,
userId: string,
): Promise<void> {
const response = await api.delete(
`/channels/${channelId}/permissions/users/${userId}`,
)
await parseResponse<void>(response)
}
// ---------------------------------------------------------------------------
// Permissions canal - rôle
// ---------------------------------------------------------------------------
async function getChannelRolePermission(
channelId: string,
roleId: string,
): Promise<ChannelRolePermission> {
const response = await api.get(
`/channels/${channelId}/permissions/roles/${roleId}`,
)
const dto = await parseResponse<ChannelRolePermissionDto>(response)
return channelRolePermissionFromDto(dto)
}
async function setChannelRolePermission(
channelId: string,
roleId: string,
permissions: PermissionMaskInput,
): Promise<ChannelRolePermission> {
const response = await api.put(
`/channels/${channelId}/permissions/roles/${roleId}`,
{
permissions: permissionMaskToJson(permissions),
},
)
const dto = await parseResponse<ChannelRolePermissionDto>(response)
return channelRolePermissionFromDto(dto)
}
async function removeChannelRolePermission(
channelId: string,
roleId: string,
): Promise<void> {
const response = await api.delete(
`/channels/${channelId}/permissions/roles/${roleId}`,
)
await parseResponse<void>(response)
}
return {
getServerUserPermission,
setServerUserPermission,
removeServerUserPermission,
getServerRolePermission,
setServerRolePermission,
removeServerRolePermission,
getChannelUserPermission,
setChannelUserPermission,
removeChannelUserPermission,
getChannelRolePermission,
setChannelRolePermission,
removeChannelRolePermission,
}
}
+33 -5
View File
@@ -1,11 +1,39 @@
<script lang="ts" setup>
import {ref} from 'vue'
import ServerPermissionEditor from '@/components/permissions/ServerPermissionEditor.vue'
import ChannelPermissionEditor from '@/components/permissions/ChannelPermissionEditor.vue'
import {
type ChannelPermissionMask,
type ServerPermissionMask,
toChannelPermissionMask,
toServerPermissionMask,
} from '@/types/permissions'
const serverPermissions = ref<ServerPermissionMask>(
toServerPermissionMask(0),
)
const channelPermissions = ref<ChannelPermissionMask>(
toChannelPermissionMask(0),
)
</script>
<template>
<v-container>
<v-row>
<v-col cols="12" md="6">
<ServerPermissionEditor
v-model="serverPermissions"
title="Test des permissions serveur"
/>
</v-col>
</template>
<style scoped>
</style>
<v-col cols="12" md="6">
<ChannelPermissionEditor
v-model="channelPermissions"
title="Test des permissions canal"
/>
</v-col>
</v-row>
</v-container>
</template>
+7 -5
View File
@@ -1,7 +1,9 @@
<template>
<HelloWorld />
</template>
<script lang="ts" setup>
import HelloWorld from '@/components/HelloWorld.vue'
</script>
<template>
<div>
Hello
</div>
</template>
+445
View File
@@ -0,0 +1,445 @@
export type PermissionMaskInput = bigint | number | string
export type ServerPermissionMask = bigint & {
readonly __brand: 'ServerPermissionMask'
}
export type ChannelPermissionMask = bigint & {
readonly __brand: 'ChannelPermissionMask'
}
export interface ServerPermissionDefinition {
key: string
label: string
description?: string
bit: ServerPermissionMask
category: 'management' | 'members'
}
export interface ChannelPermissionDefinition {
key: string
label: string
description?: string
bit: ChannelPermissionMask
category: 'chat' | 'voice' | 'management'
}
export interface ServerUserPermission {
id: string
server_id: string
user_id: string
permissions: ServerPermissionMask
}
export interface ServerRolePermission {
id: string
server_id: string
role_id: string
permissions: ServerPermissionMask
}
export interface ChannelUserPermission {
id: string
channel_id: string
user_id: string
permissions: ChannelPermissionMask
}
export interface ChannelRolePermission {
id: string
channel_id: string
role_id: string
permissions: ChannelPermissionMask
}
export interface ServerUserPermissionDto {
id: string
server_id: string
user_id: string
permissions: number | string
}
export interface ServerRolePermissionDto {
id: string
server_id: string
role_id: string
permissions: number | string
}
export interface ChannelUserPermissionDto {
id: string
channel_id: string
user_id: string
permissions: number | string
}
export interface ChannelRolePermissionDto {
id: string
channel_id: string
role_id: string
permissions: number | string
}
function asServerPermissionMask(value: bigint): ServerPermissionMask {
return value as ServerPermissionMask
}
function asChannelPermissionMask(value: bigint): ChannelPermissionMask {
return value as ChannelPermissionMask
}
function toBigInt(value: PermissionMaskInput): bigint {
if (typeof value === 'bigint') {
return value
}
if (typeof value === 'number') {
if (!Number.isSafeInteger(value) || value < 0) {
throw new Error(`Invalid permission mask: ${value}`)
}
return BigInt(value)
}
if (!/^\d+$/.test(value)) {
throw new Error(`Invalid permission mask: ${value}`)
}
return BigInt(value)
}
export function toServerPermissionMask(
value: PermissionMaskInput,
): ServerPermissionMask {
return asServerPermissionMask(toBigInt(value))
}
export function toChannelPermissionMask(
value: PermissionMaskInput,
): ChannelPermissionMask {
return asChannelPermissionMask(toBigInt(value))
}
export const SERVER_PERMISSIONS = {
MANAGE_SERVER: asServerPermissionMask(1n << 0n),
MANAGE_ROLES: asServerPermissionMask(1n << 1n),
MANAGE_CATEGORIES: asServerPermissionMask(1n << 2n),
MANAGE_CHANNELS: asServerPermissionMask(1n << 3n),
KICK_MEMBERS: asServerPermissionMask(1n << 4n),
BAN_MEMBERS: asServerPermissionMask(1n << 5n),
MANAGE_MEMBERS: asServerPermissionMask(1n << 6n),
VIEW_MEMBERS: asServerPermissionMask(1n << 7n),
} as const satisfies Record<string, ServerPermissionMask>
export const CHANNEL_PERMISSIONS = {
READ_CHANNEL: asChannelPermissionMask(1n << 0n),
SEND_MESSAGE: asChannelPermissionMask(1n << 1n),
EDIT_OWN_MESSAGE: asChannelPermissionMask(1n << 2n),
DELETE_OWN_MESSAGE: asChannelPermissionMask(1n << 3n),
EDIT_OTHERS_MESSAGES: asChannelPermissionMask(1n << 4n),
DELETE_OTHERS_MESSAGES: asChannelPermissionMask(1n << 5n),
ADD_REACTIONS: asChannelPermissionMask(1n << 6n),
ATTACH_FILES: asChannelPermissionMask(1n << 7n),
MANAGE_CHANNEL: asChannelPermissionMask(1n << 8n),
MANAGE_MESSAGES: asChannelPermissionMask(1n << 10n),
JOIN_VOICE: asChannelPermissionMask(1n << 30n),
SPEAK: asChannelPermissionMask(1n << 31n),
STREAM: asChannelPermissionMask(1n << 32n),
MUTE_SELF: asChannelPermissionMask(1n << 33n),
MUTE_OTHERS: asChannelPermissionMask(1n << 34n),
MOVE_OTHERS: asChannelPermissionMask(1n << 35n),
DISCONNECT_OTHERS: asChannelPermissionMask(1n << 36n),
MANAGE_VOICE_CHANNEL: asChannelPermissionMask(1n << 37n),
} as const satisfies Record<string, ChannelPermissionMask>
export const SERVER_PERMISSION_DEFINITIONS: ServerPermissionDefinition[] = [
{
key: 'manage_server',
label: 'Gérer le serveur',
description: 'Modifier les paramètres généraux du serveur.',
bit: SERVER_PERMISSIONS.MANAGE_SERVER,
category: 'management',
},
{
key: 'manage_roles',
label: 'Gérer les rôles',
description: 'Créer, modifier et supprimer des rôles.',
bit: SERVER_PERMISSIONS.MANAGE_ROLES,
category: 'management',
},
{
key: 'manage_categories',
label: 'Gérer les catégories',
description: 'Créer, modifier et supprimer des catégories.',
bit: SERVER_PERMISSIONS.MANAGE_CATEGORIES,
category: 'management',
},
{
key: 'manage_channels',
label: 'Gérer les canaux',
description: 'Créer, modifier et supprimer des canaux.',
bit: SERVER_PERMISSIONS.MANAGE_CHANNELS,
category: 'management',
},
{
key: 'kick_members',
label: 'Expulser des membres',
description: 'Expulser un membre du serveur.',
bit: SERVER_PERMISSIONS.KICK_MEMBERS,
category: 'members',
},
{
key: 'ban_members',
label: 'Bannir des membres',
description: 'Bannir un membre du serveur.',
bit: SERVER_PERMISSIONS.BAN_MEMBERS,
category: 'members',
},
{
key: 'manage_members',
label: 'Gérer les membres',
description: 'Modifier le profil ou les rôles dun membre.',
bit: SERVER_PERMISSIONS.MANAGE_MEMBERS,
category: 'members',
},
{
key: 'view_members',
label: 'Voir les membres',
description: 'Voir la liste des membres du serveur.',
bit: SERVER_PERMISSIONS.VIEW_MEMBERS,
category: 'members',
},
]
export const CHANNEL_PERMISSION_DEFINITIONS: ChannelPermissionDefinition[] = [
{
key: 'read_channel',
label: 'Lire le canal',
description: 'Voir le canal et son contenu.',
bit: CHANNEL_PERMISSIONS.READ_CHANNEL,
category: 'chat',
},
{
key: 'send_message',
label: 'Envoyer des messages',
bit: CHANNEL_PERMISSIONS.SEND_MESSAGE,
category: 'chat',
},
{
key: 'edit_own_message',
label: 'Modifier ses messages',
bit: CHANNEL_PERMISSIONS.EDIT_OWN_MESSAGE,
category: 'chat',
},
{
key: 'delete_own_message',
label: 'Supprimer ses messages',
bit: CHANNEL_PERMISSIONS.DELETE_OWN_MESSAGE,
category: 'chat',
},
{
key: 'edit_others_messages',
label: 'Modifier les messages des autres',
bit: CHANNEL_PERMISSIONS.EDIT_OTHERS_MESSAGES,
category: 'chat',
},
{
key: 'delete_others_messages',
label: 'Supprimer les messages des autres',
bit: CHANNEL_PERMISSIONS.DELETE_OTHERS_MESSAGES,
category: 'chat',
},
{
key: 'add_reactions',
label: 'Ajouter des réactions',
bit: CHANNEL_PERMISSIONS.ADD_REACTIONS,
category: 'chat',
},
{
key: 'attach_files',
label: 'Joindre des fichiers',
bit: CHANNEL_PERMISSIONS.ATTACH_FILES,
category: 'chat',
},
{
key: 'manage_channel',
label: 'Gérer le canal',
description: 'Modifier les paramètres du canal.',
bit: CHANNEL_PERMISSIONS.MANAGE_CHANNEL,
category: 'management',
},
{
key: 'manage_messages',
label: 'Gérer les messages',
bit: CHANNEL_PERMISSIONS.MANAGE_MESSAGES,
category: 'management',
},
{
key: 'join_voice',
label: 'Rejoindre le vocal',
bit: CHANNEL_PERMISSIONS.JOIN_VOICE,
category: 'voice',
},
{
key: 'speak',
label: 'Parler',
bit: CHANNEL_PERMISSIONS.SPEAK,
category: 'voice',
},
{
key: 'stream',
label: 'Diffuser',
bit: CHANNEL_PERMISSIONS.STREAM,
category: 'voice',
},
{
key: 'mute_self',
label: 'Se mettre en sourdine',
bit: CHANNEL_PERMISSIONS.MUTE_SELF,
category: 'voice',
},
{
key: 'mute_others',
label: 'Rendre les autres muets',
bit: CHANNEL_PERMISSIONS.MUTE_OTHERS,
category: 'voice',
},
{
key: 'move_others',
label: 'Déplacer les autres',
bit: CHANNEL_PERMISSIONS.MOVE_OTHERS,
category: 'voice',
},
{
key: 'disconnect_others',
label: 'Déconnecter les autres',
bit: CHANNEL_PERMISSIONS.DISCONNECT_OTHERS,
category: 'voice',
},
{
key: 'manage_voice_channel',
label: 'Gérer le canal vocal',
bit: CHANNEL_PERMISSIONS.MANAGE_VOICE_CHANNEL,
category: 'management',
},
]
export function hasServerPermission(
mask: ServerPermissionMask,
required: ServerPermissionMask,
): boolean {
return (mask & required) === required
}
export function grantServerPermission(
mask: ServerPermissionMask,
permission: ServerPermissionMask,
): ServerPermissionMask {
return asServerPermissionMask(mask | permission)
}
export function revokeServerPermission(
mask: ServerPermissionMask,
permission: ServerPermissionMask,
): ServerPermissionMask {
return asServerPermissionMask(mask & ~permission)
}
export function toggleServerPermission(
mask: ServerPermissionMask,
permission: ServerPermissionMask,
enabled: boolean,
): ServerPermissionMask {
return enabled
? grantServerPermission(mask, permission)
: revokeServerPermission(mask, permission)
}
export function hasChannelPermission(
mask: ChannelPermissionMask,
required: ChannelPermissionMask,
): boolean {
return (mask & required) === required
}
export function grantChannelPermission(
mask: ChannelPermissionMask,
permission: ChannelPermissionMask,
): ChannelPermissionMask {
return asChannelPermissionMask(mask | permission)
}
export function revokeChannelPermission(
mask: ChannelPermissionMask,
permission: ChannelPermissionMask,
): ChannelPermissionMask {
return asChannelPermissionMask(mask & ~permission)
}
export function toggleChannelPermission(
mask: ChannelPermissionMask,
permission: ChannelPermissionMask,
enabled: boolean,
): ChannelPermissionMask {
return enabled
? grantChannelPermission(mask, permission)
: revokeChannelPermission(mask, permission)
}
export function permissionMaskToJson(
mask: PermissionMaskInput,
): number | string {
const value = toBigInt(mask)
if (value < 0n) {
throw new Error('Permission mask cannot be negative')
}
return value <= BigInt(Number.MAX_SAFE_INTEGER)
? Number(value)
: value.toString()
}
export function serverUserPermissionFromDto(
dto: ServerUserPermissionDto,
): ServerUserPermission {
return {
id: dto.id,
server_id: dto.server_id,
user_id: dto.user_id,
permissions: toServerPermissionMask(dto.permissions),
}
}
export function serverRolePermissionFromDto(
dto: ServerRolePermissionDto,
): ServerRolePermission {
return {
id: dto.id,
server_id: dto.server_id,
role_id: dto.role_id,
permissions: toServerPermissionMask(dto.permissions),
}
}
export function channelUserPermissionFromDto(
dto: ChannelUserPermissionDto,
): ChannelUserPermission {
return {
id: dto.id,
channel_id: dto.channel_id,
user_id: dto.user_id,
permissions: toChannelPermissionMask(dto.permissions),
}
}
export function channelRolePermissionFromDto(
dto: ChannelRolePermissionDto,
): ChannelRolePermission {
return {
id: dto.id,
channel_id: dto.channel_id,
role_id: dto.role_id,
permissions: toChannelPermissionMask(dto.permissions),
}
}