File size: 1,245 Bytes
00a912e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { PureAbility, AbilityBuilder } from '@casl/ability'
import type { UserRole } from './types.js'

export type Actions =
  | 'play'
  | 'pause'
  | 'seek'
  | 'next'
  | 'prev'
  | 'set-mode'
  | 'add'
  | 'remove'
  | 'reorder'
  | 'manage'
  | 'vote'
  | 'set-role'

export type Subjects = 'Player' | 'Queue' | 'Room' | 'all'

export type AppAbility = PureAbility<[Actions, Subjects]>

/**
 * Define CASL abilities for a given user role.
 *
 * - Owner: manage all (播放控制 + 队列 + 房间设置 + 角色管理 + 投票否决)
 * - Admin: 全部播放控制 + 全部队列权限
 * - Member: 仅添加歌曲 + 发起投票
 */
export function defineAbilityFor(role: UserRole): AppAbility {
  const { can, build } = new AbilityBuilder<AppAbility>(PureAbility)

  switch (role) {
    case 'owner':
      can('manage', 'all')
      break
    case 'admin':
      can('play', 'Player')
      can('pause', 'Player')
      can('seek', 'Player')
      can('next', 'Player')
      can('prev', 'Player')
      can('set-mode', 'Player')
      can('add', 'Queue')
      can('remove', 'Queue')
      can('reorder', 'Queue')
      break
    case 'member':
      can('add', 'Queue')
      can('vote', 'Player')
      break
  }

  return build()
}