feat: add licensing and access controls

This commit is contained in:
ShukeBta
2026-05-29 12:47:54 +08:00
parent 2f7ec3ab17
commit 27df93fa3d
61 changed files with 2032 additions and 237 deletions
+6
View File
@@ -4,6 +4,12 @@ import type { AccessLog, Setting, User } from '../types'
export const adminAPI = {
listUsers: () => api.get<User[]>('/admin/users').then((r) => r.data),
createUser: (payload: { username: string; password: string }) =>
api.post<User>('/admin/users', payload).then((r) => r.data),
updateUser: (id: string, payload: { username: string }) =>
api.patch<User>(`/admin/users/${id}`, payload).then((r) => r.data),
deleteUser: (id: string) => api.delete(`/admin/users/${id}`).then((r) => r.data),
listSettings: () => api.get<Setting[]>('/admin/settings').then((r) => r.data),
+5
View File
@@ -23,6 +23,11 @@ export interface ExternalMediaResult {
bangumi_id?: number
douban_id?: string
subscribe_keyword: string
total_episodes?: number
downloaded_episodes?: number
local_media_count?: number
missing_episodes?: number[]
in_library?: boolean
}
export const aiAPI = {
+1
View File
@@ -25,6 +25,7 @@ export interface LicenseStatus {
/** Whether a license is currently active */
active: boolean
activation?: LicenseActivation
max_users?: number
/** Error or status message */
message?: string
}
+14
View File
@@ -21,6 +21,12 @@ export interface PlaylistDetail {
items: Media[]
}
export interface ExternalPlayer {
name: string
scheme: string
url: string
}
export const playbackAPI = {
recordProgress: (mediaId: string, positionMs: number, durationMs: number) =>
api
@@ -61,4 +67,12 @@ export const playbackAPI = {
deletePlaylist: (id: string) =>
api.delete(`/playlists/${id}`).then((r) => r.data),
externalPlayers: (mediaId: string) =>
api
.get<{ players: ExternalPlayer[]; url?: string }>(`/playback/${mediaId}/external-players`)
.then((r) => r.data),
externalURL: (mediaId: string) =>
api.get<{ url: string; token: string }>(`/playback/${mediaId}/external-url`).then((r) => r.data),
}
+1
View File
@@ -25,6 +25,7 @@ export const subscriptionsAPI = {
exclude_words?: string
wash_enabled?: boolean
wash_priority?: string
total_episodes?: number
priority?: number
enabled?: boolean
}) =>