more fix and update

This commit is contained in:
lendry
2026-06-24 20:15:19 +03:00
parent dcab6557d3
commit 9727cf3f35
53 changed files with 3479 additions and 494 deletions

View File

@@ -16,6 +16,15 @@ interface MediaStreamPayload {
fileName?: string;
}
interface MediaUploadPayload {
purpose: 'media-upload';
storageKey: string;
contentType: string;
userId: string;
}
const UPLOAD_TTL_SECONDS = 300;
@Injectable()
export class MediaService {
constructor(
@@ -34,8 +43,7 @@ export class MediaService {
}
const extension = this.minio.extensionForContentType(contentType);
const storageKey = `avatars/${userId}/${crypto.randomUUID()}.${extension}`;
const presigned = await this.minio.createPresignedUploadUrl(storageKey, contentType);
return { ...presigned, storageKey };
return this.createUploadTarget(userId, storageKey, contentType);
}
async confirmAvatar(userId: string, storageKey: string) {
@@ -102,8 +110,7 @@ export class MediaService {
const extension = this.minio.extensionForContentType(contentType);
const storageKey = `documents/${userId}/${documentId}/${crypto.randomUUID()}.${extension}`;
const presigned = await this.minio.createPresignedUploadUrl(storageKey, contentType);
return { ...presigned, storageKey };
return this.createUploadTarget(userId, storageKey, contentType);
}
async resolveStreamToken(token: string, requesterId?: string) {
@@ -186,8 +193,7 @@ export class MediaService {
}
const extension = this.minio.extensionForContentType(contentType);
const storageKey = `families/${groupId}/${crypto.randomUUID()}.${extension}`;
const presigned = await this.minio.createPresignedUploadUrl(storageKey, contentType);
return { ...presigned, storageKey };
return this.createUploadTarget(requesterId, storageKey, contentType);
}
async confirmFamilyAvatar(requesterId: string, groupId: string, storageKey: string) {
@@ -221,8 +227,7 @@ export class MediaService {
}
const extension = this.minio.extensionForChatMedia(normalized, fileName);
const storageKey = `chat/${roomId}/${crypto.randomUUID()}.${extension}`;
const presigned = await this.minio.createPresignedUploadUrl(storageKey, normalized);
return { ...presigned, storageKey };
return this.createUploadTarget(requesterId, storageKey, normalized);
}
async getChatMediaAccessUrl(requesterId: string, roomId: string, storageKey: string, fileName?: string) {
@@ -241,6 +246,37 @@ export class MediaService {
return roomId;
}
private async createUploadTarget(userId: string, storageKey: string, contentType: string) {
const viaApi = this.config.get<string>('MINIO_UPLOAD_VIA_API', 'true') !== 'false';
const expiresAt = new Date(Date.now() + UPLOAD_TTL_SECONDS * 1000).toISOString();
if (viaApi) {
const uploadToken = await this.jwt.signAsync(
{
purpose: 'media-upload',
storageKey,
contentType,
userId
} satisfies MediaUploadPayload,
{
secret: this.config.getOrThrow<string>('JWT_ACCESS_SECRET'),
expiresIn: UPLOAD_TTL_SECONDS,
issuer: 'id.lendry.ru'
}
);
const publicApiUrl = this.config.get<string>('PUBLIC_API_URL', 'http://localhost:3001').replace(/\/$/, '');
return {
uploadUrl: `${publicApiUrl}/media/upload`,
uploadToken,
storageKey,
expiresAt
};
}
const presigned = await this.minio.createPresignedUploadUrl(storageKey, contentType, UPLOAD_TTL_SECONDS);
return { ...presigned, storageKey };
}
private async createStreamAccessUrl(
storageKey: string,
ownerId: string,