fix and update
This commit is contained in:
@@ -26,7 +26,7 @@ export function getAdminLandingPath(user: PublicUser): string {
|
||||
return '/admin/oauth';
|
||||
}
|
||||
|
||||
export function canAccessAdminSection(user: PublicUser, section: 'users' | 'oauth' | 'settings' | 'rbac' | 'bots') {
|
||||
export function canAccessAdminSection(user: PublicUser, section: 'users' | 'oauth' | 'settings' | 'rbac' | 'bots' | 'releases') {
|
||||
switch (section) {
|
||||
case 'users':
|
||||
return Boolean(user.canViewUsers || user.canManageUsers);
|
||||
@@ -35,6 +35,7 @@ export function canAccessAdminSection(user: PublicUser, section: 'users' | 'oaut
|
||||
case 'oauth':
|
||||
return Boolean(user.canViewOAuth || user.canManageOAuth);
|
||||
case 'settings':
|
||||
case 'releases':
|
||||
return Boolean(user.canManageSettings);
|
||||
case 'rbac':
|
||||
return Boolean(user.canManageRoles);
|
||||
|
||||
@@ -1727,5 +1727,111 @@ export async function fetchFamilyPresence(groupId: string, token?: string | null
|
||||
return apiFetch<FamilyPresence>(`/family/groups/${groupId}/presence`, {}, accessToken, true, { silent: true });
|
||||
}
|
||||
|
||||
export type AppReleasePlatform = 'ANDROID' | 'WINDOWS';
|
||||
|
||||
export interface AppRelease {
|
||||
id: string;
|
||||
platform: AppReleasePlatform;
|
||||
version: string;
|
||||
versionCode: number;
|
||||
fileName: string;
|
||||
storageKey: string;
|
||||
fileSize: string;
|
||||
sha256: string;
|
||||
releaseNotes?: string;
|
||||
isPublished: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface AppUpdateCheckResponse {
|
||||
updateAvailable: boolean;
|
||||
latest?: AppRelease;
|
||||
}
|
||||
|
||||
export async function fetchPublicAppReleases(platform?: AppReleasePlatform) {
|
||||
const query = platform ? `?platform=${platform}` : '';
|
||||
return apiFetch<{ releases: AppRelease[] }>(`/releases${query}`, {}, null, true, { silent: true });
|
||||
}
|
||||
|
||||
export async function fetchLatestAppRelease(platform: AppReleasePlatform) {
|
||||
return apiFetch<AppRelease>(`/releases/latest/${platform.toLowerCase()}`, {}, null, true, { silent: true });
|
||||
}
|
||||
|
||||
export async function checkAppUpdate(platform: AppReleasePlatform, versionCode: number) {
|
||||
return apiFetch<AppUpdateCheckResponse>(
|
||||
`/releases/check?platform=${platform}&versionCode=${versionCode}`,
|
||||
{},
|
||||
null,
|
||||
true,
|
||||
{ silent: true }
|
||||
);
|
||||
}
|
||||
|
||||
export function buildAppReleaseDownloadUrl(platform: AppReleasePlatform, releaseId?: string) {
|
||||
const base = getApiUrl().replace(/\/$/, '');
|
||||
const slug = platform.toLowerCase();
|
||||
return releaseId ? `${base}/releases/download/${slug}/${releaseId}` : `${base}/releases/download/${slug}`;
|
||||
}
|
||||
|
||||
export async function fetchAdminAppReleases(token: string, platform?: AppReleasePlatform) {
|
||||
const query = platform ? `?platform=${platform}` : '';
|
||||
return apiFetch<{ releases: AppRelease[] }>(`/admin/releases${query}`, {}, token);
|
||||
}
|
||||
|
||||
export async function uploadAdminAppRelease(
|
||||
token: string,
|
||||
payload: {
|
||||
platform: AppReleasePlatform;
|
||||
version: string;
|
||||
versionCode: number;
|
||||
releaseNotes?: string;
|
||||
file: File;
|
||||
},
|
||||
onProgress?: (percent: number) => void
|
||||
) {
|
||||
const formData = new FormData();
|
||||
formData.append('platform', payload.platform);
|
||||
formData.append('version', payload.version.trim());
|
||||
formData.append('versionCode', String(payload.versionCode));
|
||||
if (payload.releaseNotes?.trim()) {
|
||||
formData.append('releaseNotes', payload.releaseNotes.trim());
|
||||
}
|
||||
formData.append('file', payload.file, payload.file.name);
|
||||
|
||||
const apiBase = getApiUrl().replace(/\/$/, '');
|
||||
const response = await platformFetch(`${apiBase}/admin/releases/upload`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const body = await response.json().catch(() => ({}));
|
||||
const message = typeof body?.message === 'string' ? body.message : 'Не удалось загрузить релиз';
|
||||
throw new ApiError(message, response.status, 'UPLOAD_FAILED');
|
||||
}
|
||||
|
||||
onProgress?.(100);
|
||||
return (await response.json()) as AppRelease;
|
||||
}
|
||||
|
||||
export async function updateAdminAppRelease(
|
||||
token: string,
|
||||
releaseId: string,
|
||||
patch: { isPublished?: boolean; releaseNotes?: string }
|
||||
) {
|
||||
return apiFetch<AppRelease>(`/admin/releases/${releaseId}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(patch)
|
||||
}, token);
|
||||
}
|
||||
|
||||
export async function deleteAdminAppRelease(token: string, releaseId: string) {
|
||||
return apiFetch<{ deleted: boolean }>(`/admin/releases/${releaseId}`, { method: 'DELETE' }, token);
|
||||
}
|
||||
|
||||
/** @deprecated Используйте getWsUrl() — URL может переключаться на same-origin /idp-api/ws в браузере */
|
||||
export const WS_URL = configuredWsUrl;
|
||||
|
||||
Reference in New Issue
Block a user