File size: 2,554 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import type { Playlist, MusicSource } from '@music-together/shared'
import * as neteaseAuth from './neteaseAuthService.js'
import * as kugouAuth from './kugouAuthService.js'
import * as tencentAuth from './tencentAuthService.js'
import * as bilibiliAuth from './bilibiliAuthService.js'

// ---------------------------------------------------------------------------
// 统一认证服务接口
// ---------------------------------------------------------------------------

/**
 * 用户信息数据(三平台通用)
 */
export interface UserInfoData {
  nickname: string
  vipType: number
  /** Sanitized display label, never an upstream HTML fragment. */
  vipLabel?: string
  /** Optional provider-specific progression level. */
  vipLevel?: number
  userId: number
}

/**
 * getUserInfo 统一返回类型
 * - ok=true: 验证成功,包含用户信息
 * - ok=false + reason='expired': Cookie 已过期
 * - ok=false + reason='error': 临时错误(网络/超时等)
 */
export type GetUserInfoResult = { ok: true; data: UserInfoData } | { ok: false; reason: 'expired' | 'error' }

/**
 * 每个音乐平台认证服务必须实现的接口
 */
export interface AuthProvider {
  /** 生成 QR 扫码登录二维码 */
  generateQrCode(): Promise<{ key: string; qrimg: string } | null>

  /** 检查 QR 扫码状态 */
  checkQrStatus(key: string): Promise<{
    status: number
    message: string
    cookie?: string
  }>

  /** 验证 Cookie 并获取用户信息 */
  getUserInfo(cookie: string): Promise<GetUserInfoResult>

  /** 获取用户歌单列表 */
  getUserPlaylists(cookie: string): Promise<Playlist[]>
}

const unsupportedAuthProvider: AuthProvider = {
  async generateQrCode() {
    return null
  },
  async checkQrStatus() {
    return { status: 800, message: '暂不支持该平台登录' }
  },
  async getUserInfo() {
    return { ok: false, reason: 'error' }
  },
  async getUserPlaylists() {
    return []
  },
}

// ---------------------------------------------------------------------------
// 平台策略映射
// ---------------------------------------------------------------------------

/**
 * 平台 → AuthProvider 映射表
 *
 * authController 通过此映射表获取对应平台的认证服务实例,
 * 从而用一份代码处理所有平台的 QR 登录/Cookie 验证/歌单获取。
 */
export const AUTH_PROVIDERS: Record<MusicSource, AuthProvider> = {
  netease: neteaseAuth,
  kugou: kugouAuth,
  kugou_concept: kugouAuth.conceptAuthProvider,
  tencent: tencentAuth,
  bilibili: bilibiliAuth,
}