@solidxai/core 0.1.12-beta.1 → 0.1.12-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/media-file-types.d.ts +5 -0
- package/dist/constants/media-file-types.d.ts.map +1 -0
- package/dist/constants/media-file-types.js +27 -0
- package/dist/constants/media-file-types.js.map +1 -0
- package/dist/controllers/media.controller.d.ts +14 -11
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.js +72 -33
- package/dist/controllers/media.controller.js.map +1 -1
- package/dist/dtos/create-chatter-message.dto.d.ts +1 -0
- package/dist/dtos/create-chatter-message.dto.d.ts.map +1 -1
- package/dist/dtos/create-chatter-message.dto.js +7 -1
- package/dist/dtos/create-chatter-message.dto.js.map +1 -1
- package/dist/dtos/create-media.dto.d.ts +1 -0
- package/dist/dtos/create-media.dto.d.ts.map +1 -1
- package/dist/dtos/create-media.dto.js +7 -1
- package/dist/dtos/create-media.dto.js.map +1 -1
- package/dist/dtos/post-chatter-message.dto.d.ts +1 -0
- package/dist/dtos/post-chatter-message.dto.d.ts.map +1 -1
- package/dist/dtos/post-chatter-message.dto.js +6 -1
- package/dist/dtos/post-chatter-message.dto.js.map +1 -1
- package/dist/dtos/update-chatter-message.dto.d.ts +1 -0
- package/dist/dtos/update-chatter-message.dto.d.ts.map +1 -1
- package/dist/dtos/update-chatter-message.dto.js +8 -1
- package/dist/dtos/update-chatter-message.dto.js.map +1 -1
- package/dist/dtos/update-chatter-note-message.dto.d.ts +1 -0
- package/dist/dtos/update-chatter-note-message.dto.d.ts.map +1 -1
- package/dist/dtos/update-chatter-note-message.dto.js +7 -1
- package/dist/dtos/update-chatter-note-message.dto.js.map +1 -1
- package/dist/dtos/update-media.dto.d.ts +1 -0
- package/dist/dtos/update-media.dto.d.ts.map +1 -1
- package/dist/dtos/update-media.dto.js +7 -1
- package/dist/dtos/update-media.dto.js.map +1 -1
- package/dist/entities/chatter-message.entity.d.ts +1 -0
- package/dist/entities/chatter-message.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message.entity.js +5 -1
- package/dist/entities/chatter-message.entity.js.map +1 -1
- package/dist/entities/media.entity.d.ts +1 -0
- package/dist/entities/media.entity.d.ts.map +1 -1
- package/dist/entities/media.entity.js +9 -1
- package/dist/entities/media.entity.js.map +1 -1
- package/dist/enums/auth-type.enum.d.ts +2 -1
- package/dist/enums/auth-type.enum.d.ts.map +1 -1
- package/dist/enums/auth-type.enum.js +1 -0
- package/dist/enums/auth-type.enum.js.map +1 -1
- package/dist/guards/authentication.guard.d.ts +3 -1
- package/dist/guards/authentication.guard.d.ts.map +1 -1
- package/dist/guards/authentication.guard.js +5 -1
- package/dist/guards/authentication.guard.js.map +1 -1
- package/dist/guards/media-signed-url.guard.d.ts +9 -0
- package/dist/guards/media-signed-url.guard.d.ts.map +1 -0
- package/dist/guards/media-signed-url.guard.js +49 -0
- package/dist/guards/media-signed-url.guard.js.map +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +10 -13
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/interfaces/chatter-mention-notification.interface.d.ts +27 -0
- package/dist/interfaces/chatter-mention-notification.interface.d.ts.map +1 -0
- package/dist/interfaces/chatter-mention-notification.interface.js +3 -0
- package/dist/interfaces/chatter-mention-notification.interface.js.map +1 -0
- package/dist/jobs/chatter-mention-notification-email-queue-handler.service.d.ts +17 -0
- package/dist/jobs/chatter-mention-notification-email-queue-handler.service.d.ts.map +1 -0
- package/dist/jobs/chatter-mention-notification-email-queue-handler.service.js +106 -0
- package/dist/jobs/chatter-mention-notification-email-queue-handler.service.js.map +1 -0
- package/dist/jobs/database/chatter-mention-notification-email-publisher-database.service.d.ts +12 -0
- package/dist/jobs/database/chatter-mention-notification-email-publisher-database.service.d.ts.map +1 -0
- package/dist/jobs/database/chatter-mention-notification-email-publisher-database.service.js +39 -0
- package/dist/jobs/database/chatter-mention-notification-email-publisher-database.service.js.map +1 -0
- package/dist/jobs/database/chatter-mention-notification-email-queue-options-database.d.ts +8 -0
- package/dist/jobs/database/chatter-mention-notification-email-queue-options-database.d.ts.map +1 -0
- package/dist/jobs/database/chatter-mention-notification-email-queue-options-database.js +10 -0
- package/dist/jobs/database/chatter-mention-notification-email-queue-options-database.js.map +1 -0
- package/dist/jobs/database/chatter-mention-notification-email-subscriber-database.service.d.ts +20 -0
- package/dist/jobs/database/chatter-mention-notification-email-subscriber-database.service.d.ts.map +1 -0
- package/dist/jobs/database/chatter-mention-notification-email-subscriber-database.service.js +48 -0
- package/dist/jobs/database/chatter-mention-notification-email-subscriber-database.service.js.map +1 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-publisher.service.d.ts +12 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-publisher.service.d.ts.map +1 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-publisher.service.js +39 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-publisher.service.js.map +1 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-queue-options.d.ts +8 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-queue-options.d.ts.map +1 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-queue-options.js +10 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-queue-options.js.map +1 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-subscriber.service.d.ts +18 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-subscriber.service.d.ts.map +1 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-subscriber.service.js +45 -0
- package/dist/jobs/rabbitmq/chatter-mention-notification-email-subscriber.service.js.map +1 -0
- package/dist/jobs/redis/chatter-mention-notification-email-publisher-redis.service.d.ts +12 -0
- package/dist/jobs/redis/chatter-mention-notification-email-publisher-redis.service.d.ts.map +1 -0
- package/dist/jobs/redis/chatter-mention-notification-email-publisher-redis.service.js +39 -0
- package/dist/jobs/redis/chatter-mention-notification-email-publisher-redis.service.js.map +1 -0
- package/dist/jobs/redis/chatter-mention-notification-email-queue-options-redis.d.ts +8 -0
- package/dist/jobs/redis/chatter-mention-notification-email-queue-options-redis.d.ts.map +1 -0
- package/dist/jobs/redis/chatter-mention-notification-email-queue-options-redis.js +10 -0
- package/dist/jobs/redis/chatter-mention-notification-email-queue-options-redis.js.map +1 -0
- package/dist/jobs/redis/chatter-mention-notification-email-subscriber-redis.service.d.ts +18 -0
- package/dist/jobs/redis/chatter-mention-notification-email-subscriber-redis.service.d.ts.map +1 -0
- package/dist/jobs/redis/chatter-mention-notification-email-subscriber-redis.service.js +45 -0
- package/dist/jobs/redis/chatter-mention-notification-email-subscriber-redis.service.js.map +1 -0
- package/dist/repository/media.repository.d.ts.map +1 -1
- package/dist/repository/media.repository.js +2 -0
- package/dist/repository/media.repository.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +109 -3
- package/dist/services/chatter-message.service.d.ts +7 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +85 -4
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/media-download-url.service.d.ts +21 -0
- package/dist/services/media-download-url.service.d.ts.map +1 -0
- package/dist/services/media-download-url.service.js +67 -0
- package/dist/services/media-download-url.service.js.map +1 -0
- package/dist/services/media-storage.utils.d.ts +27 -0
- package/dist/services/media-storage.utils.d.ts.map +1 -0
- package/dist/services/media-storage.utils.js +82 -0
- package/dist/services/media-storage.utils.js.map +1 -0
- package/dist/services/media.service.d.ts +20 -4
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +157 -55
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts +4 -4
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +37 -63
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts +5 -5
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js +37 -38
- package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +25 -1
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.js +1 -1
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/package.json +1 -1
- package/src/constants/media-file-types.ts +44 -0
- package/src/controllers/media.controller.ts +44 -24
- package/src/dtos/create-chatter-message.dto.ts +5 -0
- package/src/dtos/create-media.dto.ts +8 -3
- package/src/dtos/post-chatter-message.dto.ts +4 -0
- package/src/dtos/update-chatter-message.dto.ts +6 -0
- package/src/dtos/update-chatter-note-message.dto.ts +5 -0
- package/src/dtos/update-media.dto.ts +8 -3
- package/src/entities/chatter-message.entity.ts +3 -0
- package/src/entities/media.entity.ts +4 -1
- package/src/enums/auth-type.enum.ts +1 -0
- package/src/guards/authentication.guard.ts +3 -0
- package/src/guards/media-signed-url.guard.ts +41 -0
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +12 -24
- package/src/interfaces/chatter-mention-notification.interface.ts +29 -0
- package/src/jobs/chatter-mention-notification-email-queue-handler.service.ts +114 -0
- package/src/jobs/database/chatter-mention-notification-email-publisher-database.service.ts +23 -0
- package/src/jobs/database/chatter-mention-notification-email-queue-options-database.ts +9 -0
- package/src/jobs/database/chatter-mention-notification-email-subscriber-database.service.ts +32 -0
- package/src/jobs/rabbitmq/chatter-mention-notification-email-publisher.service.ts +23 -0
- package/src/jobs/rabbitmq/chatter-mention-notification-email-queue-options.ts +9 -0
- package/src/jobs/rabbitmq/chatter-mention-notification-email-subscriber.service.ts +30 -0
- package/src/jobs/redis/chatter-mention-notification-email-publisher-redis.service.ts +23 -0
- package/src/jobs/redis/chatter-mention-notification-email-queue-options-redis.ts +9 -0
- package/src/jobs/redis/chatter-mention-notification-email-subscriber-redis.service.ts +30 -0
- package/src/repository/media.repository.ts +2 -0
- package/src/seeders/seed-data/email-templates/chatter-mention-notification.handlebars.html +200 -0
- package/src/seeders/seed-data/solid-core-metadata.json +109 -3
- package/src/services/chatter-message.service.ts +97 -2
- package/src/services/media-download-url.service.ts +67 -0
- package/src/services/media-storage.utils.ts +79 -0
- package/src/services/media.service.ts +189 -59
- package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +52 -76
- package/src/services/mediaStorageProviders/file-storage-provider.ts +44 -48
- package/src/solid-core.module.ts +35 -2
- package/src/subscribers/audit.subscriber.ts +1 -1
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
import { Injectable, Logger } from "@nestjs/common";
|
|
2
|
-
import { ConfigService } from "@nestjs/config";
|
|
3
|
-
import { CommonEntity } from "src/entities/common.entity";
|
|
4
2
|
import { FieldMetadata } from "src/entities/field-metadata.entity";
|
|
5
3
|
import { Media } from "src/entities/media.entity";
|
|
4
|
+
import { MediaStorageProviderMetadata } from "src/entities/media-storage-provider-metadata.entity";
|
|
6
5
|
import { MediaStorageProvider } from "src/interfaces";
|
|
7
6
|
import { MediaRepository } from "src/repository/media.repository";
|
|
8
7
|
import { DiskFileService } from "src/services/file";
|
|
9
8
|
import { Readable } from "stream";
|
|
10
|
-
import * as path from "path";
|
|
11
9
|
import * as fs from "fs";
|
|
12
10
|
import { SettingService } from "../setting.service";
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
11
|
+
import { MediaDownloadUrlService } from "src/services/media-download-url.service";
|
|
12
|
+
import { buildDiskMediaPath, buildMediaRecordCreateInput, buildStoredMediaFileName, resolveStoredMediaIsPublic, } from "src/services/media-storage.utils";
|
|
15
13
|
|
|
16
14
|
@Injectable()
|
|
17
15
|
export class FileStorageProvider<T> implements MediaStorageProvider<T> {
|
|
18
16
|
private logger = new Logger(FileStorageProvider.name);
|
|
19
17
|
|
|
20
18
|
constructor(
|
|
21
|
-
// @Inject(appBuilderConfig.KEY)
|
|
22
|
-
// private readonly appBuilderConfiguration: ConfigType<typeof appBuilderConfig>,
|
|
23
|
-
private readonly configService: ConfigService,
|
|
24
19
|
readonly fileService: DiskFileService,
|
|
25
20
|
readonly mediaRepository: MediaRepository,
|
|
26
|
-
private readonly settingService: SettingService
|
|
21
|
+
private readonly settingService: SettingService,
|
|
22
|
+
private readonly mediaDownloadUrlService: MediaDownloadUrlService,
|
|
27
23
|
|
|
28
24
|
) { }
|
|
29
25
|
|
|
@@ -32,12 +28,17 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
|
|
|
32
28
|
// throw new Error("Entity must be an instance of CommonEntity"); //FIXME This needs to be handled through generics. e.g T extends CommonEntity
|
|
33
29
|
// }
|
|
34
30
|
//@ts-ignore
|
|
35
|
-
const media = await this.mediaRepository.findByEntityIdAndFieldIdAndModelMetadataId(entity
|
|
31
|
+
const media = await this.mediaRepository.findByEntityIdAndFieldIdAndModelMetadataId(this.getEntityId(entity), mediaFieldMetadata.id, mediaFieldMetadata.model.id, ['mediaStorageProviderMetadata']);
|
|
36
32
|
// Add the full URL to the media
|
|
37
33
|
// media.forEach(m => {
|
|
38
34
|
// });
|
|
39
35
|
for (const m of media) {
|
|
40
|
-
|
|
36
|
+
const storageProvider = this.resolveMediaStorageProvider(m, mediaFieldMetadata);
|
|
37
|
+
const isPublic = resolveStoredMediaIsPublic(m.isPublic, storageProvider);
|
|
38
|
+
m.isPublic = isPublic;
|
|
39
|
+
m['_full_url'] = isPublic === false
|
|
40
|
+
? await this.mediaDownloadUrlService.resolveDownloadUrl(m.id, m.relativeUri, storageProvider)
|
|
41
|
+
: await this.fileService.getUrl(buildDiskMediaPath(m.relativeUri, this.settingService, storageProvider));
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
|
|
@@ -49,24 +50,24 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
|
|
|
49
50
|
// throw new Error("Entity must be an instance of CommonEntity"); //FIXME This needs to be handled through generics. e.g T extends CommonEntity
|
|
50
51
|
// }
|
|
51
52
|
const result: Media[] = [];
|
|
53
|
+
const storageProvider = mediaFieldMetadata.mediaStorageProvider;
|
|
52
54
|
for (const file of files) {
|
|
53
55
|
// Store the file in the configured file storage directory
|
|
54
|
-
const
|
|
56
|
+
const fileName = buildStoredMediaFileName(file);
|
|
57
|
+
const fileStoragePath = buildDiskMediaPath(fileName, this.settingService, storageProvider);
|
|
55
58
|
await this.fileService.copy(file.path, fileStoragePath);
|
|
56
59
|
await this.fileService.delete(file.path);
|
|
57
60
|
|
|
58
61
|
// Create an entry in the media table
|
|
59
|
-
const mediaEntity = await this.mediaRepository.createMedia(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
fieldMetadataId: mediaFieldMetadata.id
|
|
69
|
-
}) as unknown as Media;
|
|
62
|
+
const mediaEntity = await this.mediaRepository.createMedia(
|
|
63
|
+
buildMediaRecordCreateInput(this.getEntityId(entity), mediaFieldMetadata, storageProvider, {
|
|
64
|
+
relativeUri: fileName,
|
|
65
|
+
mimeType: file.mimetype,
|
|
66
|
+
fileSize: file.size,
|
|
67
|
+
originalFileName: file.originalname,
|
|
68
|
+
})
|
|
69
|
+
) as unknown as Media;
|
|
70
|
+
mediaEntity.isPublic = resolveStoredMediaIsPublic(mediaEntity.isPublic, storageProvider);
|
|
70
71
|
result.push(mediaEntity);
|
|
71
72
|
this.logger.debug(`Stored media with`, mediaEntity);
|
|
72
73
|
};
|
|
@@ -78,21 +79,21 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
|
|
|
78
79
|
// throw new Error("Entity must be an instance of CommonEntity"); //FIXME This needs to be handled through generics. e.g T extends CommonEntity
|
|
79
80
|
// }
|
|
80
81
|
const result: Media[] = [];
|
|
82
|
+
const storageProvider = mediaFieldMetadata.mediaStorageProvider;
|
|
81
83
|
for (const pair of streamPairs) {
|
|
82
84
|
const stream = pair[0];
|
|
83
85
|
const fileName = pair[1];
|
|
84
|
-
const fullPath = this.
|
|
86
|
+
const fullPath = buildDiskMediaPath(fileName, this.settingService, storageProvider);
|
|
85
87
|
await this.fileService.writeStream(fullPath, stream);
|
|
86
88
|
const { size: fileSize } = await fs.promises.stat(fullPath);
|
|
87
|
-
const mediaEntity = await this.mediaRepository.createMedia(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}) as unknown as Media;
|
|
89
|
+
const mediaEntity = await this.mediaRepository.createMedia(
|
|
90
|
+
buildMediaRecordCreateInput(this.getEntityId(entity), mediaFieldMetadata, storageProvider, {
|
|
91
|
+
relativeUri: fileName,
|
|
92
|
+
fileSize,
|
|
93
|
+
})
|
|
94
|
+
) as unknown as Media;
|
|
95
|
+
mediaEntity.isPublic = resolveStoredMediaIsPublic(mediaEntity.isPublic, storageProvider);
|
|
96
|
+
result.push(mediaEntity);
|
|
96
97
|
this.logger.debug(`Stored media with`, mediaEntity);
|
|
97
98
|
};
|
|
98
99
|
return result;
|
|
@@ -102,13 +103,13 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
|
|
|
102
103
|
// if (!(entity instanceof CommonEntity)) {
|
|
103
104
|
// throw new Error("Entity must be an instance of CommonEntity"); //FIXME This needs to be handled through generics. e.g T extends CommonEntity
|
|
104
105
|
// }
|
|
105
|
-
|
|
106
|
-
const existingMedia = await this.mediaRepository.findByEntityIdAndFieldIdAndModelMetadataId(
|
|
107
|
-
|
|
108
|
-
this.mediaRepository.deleteByEntityIdAndFieldIdAndModelMetadataId(entity.id, mediaFieldMetadata.id, mediaFieldMetadata.model.id);
|
|
106
|
+
const entityId = this.getEntityId(entity);
|
|
107
|
+
const existingMedia = await this.mediaRepository.findByEntityIdAndFieldIdAndModelMetadataId(entityId, mediaFieldMetadata.id, mediaFieldMetadata.model.id, ['mediaStorageProviderMetadata']);
|
|
108
|
+
await this.mediaRepository.deleteByEntityIdAndFieldIdAndModelMetadataId(entityId, mediaFieldMetadata.id, mediaFieldMetadata.model.id);
|
|
109
109
|
|
|
110
110
|
for (const media of existingMedia) {
|
|
111
|
-
|
|
111
|
+
const storageProvider = this.resolveMediaStorageProvider(media, mediaFieldMetadata);
|
|
112
|
+
await this.fileService.delete(buildDiskMediaPath(media.relativeUri, this.settingService, storageProvider));
|
|
112
113
|
}
|
|
113
114
|
// existingMedia.forEach(media => {
|
|
114
115
|
// });
|
|
@@ -118,19 +119,14 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
|
|
|
118
119
|
if (!media?.relativeUri) {
|
|
119
120
|
return;
|
|
120
121
|
}
|
|
121
|
-
await this.fileService.delete(this.
|
|
122
|
+
await this.fileService.delete(buildDiskMediaPath(media.relativeUri, this.settingService, media.mediaStorageProviderMetadata));
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
private
|
|
125
|
-
|
|
126
|
-
|| DEFAULT_MEDIA_FILE_STORAGE_DIR;
|
|
127
|
-
if (path.isAbsolute(fileName) || fileName.startsWith(`${base}/`)) {
|
|
128
|
-
return fileName;
|
|
129
|
-
}
|
|
130
|
-
return `${base}/${fileName}`;
|
|
125
|
+
private resolveMediaStorageProvider(media: Media, mediaFieldMetadata?: FieldMetadata): MediaStorageProviderMetadata | undefined {
|
|
126
|
+
return media.mediaStorageProviderMetadata || mediaFieldMetadata?.mediaStorageProvider;
|
|
131
127
|
}
|
|
132
128
|
|
|
133
|
-
private
|
|
134
|
-
return
|
|
129
|
+
private getEntityId(entity: T): number {
|
|
130
|
+
return (entity as any).id;
|
|
135
131
|
}
|
|
136
132
|
}
|
package/src/solid-core.module.ts
CHANGED
|
@@ -47,6 +47,7 @@ import { ListOfValuesService } from "./services/list-of-values.service";
|
|
|
47
47
|
// import { MediaStorageProviderMetadataSeederService } from './services/media-storage-provider-metadata-seeder.service';
|
|
48
48
|
import { MediaStorageProviderMetadataService } from "./services/media-storage-provider-metadata.service";
|
|
49
49
|
import { MediaService } from "./services/media.service";
|
|
50
|
+
import { MediaDownloadUrlService } from "./services/media-download-url.service";
|
|
50
51
|
import { ModelMetadataService } from "./services/model-metadata.service";
|
|
51
52
|
import { RemovedFieldMigrationService } from "./services/removed-field-migration.service";
|
|
52
53
|
import { ModuleMetadataExplorerService } from "./services/module-metadata-explorer.service";
|
|
@@ -55,9 +56,10 @@ import { ModulePackageService } from "./services/module-package.service";
|
|
|
55
56
|
import { SolidIntrospectService } from "./services/solid-introspect.service";
|
|
56
57
|
// import { ListOfComputedFieldProvider } from './providers/list-of-computed-field-provider.service';
|
|
57
58
|
import { ServeStaticModule } from "@nestjs/serve-static";
|
|
58
|
-
import { join } from "path";
|
|
59
|
+
import { extname, join } from "path";
|
|
59
60
|
import { RefreshModelCommand } from "./commands/refresh-model.command";
|
|
60
61
|
import { MediaController } from "./controllers/media.controller";
|
|
62
|
+
import { INLINE_SAFE_EXTENSIONS } from "./constants/media-file-types";
|
|
61
63
|
|
|
62
64
|
import { RefreshModuleCommand } from "./commands/refresh-module.command";
|
|
63
65
|
import { ModelMetadataSubscriber } from "./subscribers/model-metadata.subscriber";
|
|
@@ -106,6 +108,7 @@ import { MqMessage } from "./entities/mq-message.entity";
|
|
|
106
108
|
import { SmsTemplate } from "./entities/sms-template.entity";
|
|
107
109
|
import { AccessTokenGuard } from "./guards/access-token.guard";
|
|
108
110
|
import { ApiKeyGuard } from "./guards/api-key.guard";
|
|
111
|
+
import { MediaSignedUrlGuard } from "./guards/media-signed-url.guard";
|
|
109
112
|
import { AuthenticationGuard } from "./guards/authentication.guard";
|
|
110
113
|
import { PermissionsGuard } from "./guards/permissions.guard";
|
|
111
114
|
import { SolidRegistry } from "./helpers/solid-registry";
|
|
@@ -130,10 +133,17 @@ import { ChatterQueuePublisherRabbitmq } from "./jobs/rabbitmq/chatter-queue-pub
|
|
|
130
133
|
import { ChatterQueueSubscriberRabbitmq } from "./jobs/rabbitmq/chatter-queue-subscriber.service";
|
|
131
134
|
import { ChatterQueuePublisherDatabase } from "./jobs/database/chatter-queue-publisher-database.service";
|
|
132
135
|
import { ChatterQueueSubscriberDatabase } from "./jobs/database/chatter-queue-subscriber-database.service";
|
|
136
|
+
import { ChatterMentionNotificationEmailQueueHandler } from "./jobs/chatter-mention-notification-email-queue-handler.service";
|
|
137
|
+
import { ChatterMentionNotificationEmailQueuePublisherDatabase } from "./jobs/database/chatter-mention-notification-email-publisher-database.service";
|
|
138
|
+
import { ChatterMentionNotificationEmailQueueSubscriberDatabase } from "./jobs/database/chatter-mention-notification-email-subscriber-database.service";
|
|
139
|
+
import { ChatterMentionNotificationEmailQueuePublisherRabbitmq } from "./jobs/rabbitmq/chatter-mention-notification-email-publisher.service";
|
|
140
|
+
import { ChatterMentionNotificationEmailQueueSubscriberRabbitmq } from "./jobs/rabbitmq/chatter-mention-notification-email-subscriber.service";
|
|
133
141
|
import { ApiEmailQueuePublisherRedis } from "./jobs/redis/api-email-publisher-redis.service";
|
|
134
142
|
import { ApiEmailQueueSubscriberRedis } from "./jobs/redis/api-email-subscriber-redis.service";
|
|
135
143
|
import { ChatterQueuePublisherRedis } from "./jobs/redis/chatter-queue-publisher-redis.service";
|
|
136
144
|
import { ChatterQueueSubscriberRedis } from "./jobs/redis/chatter-queue-subscriber-redis.service";
|
|
145
|
+
import { ChatterMentionNotificationEmailQueuePublisherRedis } from "./jobs/redis/chatter-mention-notification-email-publisher-redis.service";
|
|
146
|
+
import { ChatterMentionNotificationEmailQueueSubscriberRedis } from "./jobs/redis/chatter-mention-notification-email-subscriber-redis.service";
|
|
137
147
|
import { ComputedFieldEvaluationPublisherRedis } from "./jobs/redis/computed-field-evaluation-publisher-redis.service";
|
|
138
148
|
import { ComputedFieldEvaluationSubscriberRedis } from "./jobs/redis/computed-field-evaluation-subscriber-redis.service";
|
|
139
149
|
import { GenerateCodePublisherRedis } from "./jobs/redis/generate-code-publisher-redis.service";
|
|
@@ -437,7 +447,7 @@ import { PostgresDatasourceIntrospectionProviderService } from "./services/datas
|
|
|
437
447
|
rootPath: join(process.cwd(), "media-files-storage"),
|
|
438
448
|
serveRoot: "/media-files-storage",
|
|
439
449
|
serveStaticOptions: {
|
|
440
|
-
setHeaders: (res
|
|
450
|
+
setHeaders: (res, path) => {
|
|
441
451
|
// Allow use of these files from a different origin (e.g., :3000 UI)
|
|
442
452
|
// Use 'same-site' if both origins are on the same site (localhost:* counts as same-site)
|
|
443
453
|
res.setHeader("Cross-Origin-Resource-Policy", "cross-origin"); // or 'same-site'
|
|
@@ -445,6 +455,20 @@ import { PostgresDatasourceIntrospectionProviderService } from "./services/datas
|
|
|
445
455
|
// If you need to load into <canvas> without tainting or fetch images via XHR,
|
|
446
456
|
// you can also expose CORS here (not needed for simple <img>):
|
|
447
457
|
// res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
|
|
458
|
+
|
|
459
|
+
// Prevent the browser from ever content-sniffing a served file into something
|
|
460
|
+
// more dangerous than its declared Content-Type (e.g. rendering a mislabeled
|
|
461
|
+
// upload as HTML and executing embedded script).
|
|
462
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
463
|
+
|
|
464
|
+
// Only a small allowlist of media types is ever safe to render inline. Everything
|
|
465
|
+
// else (including svg, html, and any other uploaded file) is forced to download
|
|
466
|
+
// rather than be displayed/executed by the browser, regardless of what mimetype or
|
|
467
|
+
// extension it was uploaded with.
|
|
468
|
+
if (!INLINE_SAFE_EXTENSIONS.has(extname(path).toLowerCase().replace(/^\./, ''))) {
|
|
469
|
+
res.setHeader("Content-Type", "application/octet-stream");
|
|
470
|
+
res.setHeader("Content-Disposition", "attachment");
|
|
471
|
+
}
|
|
448
472
|
},
|
|
449
473
|
},
|
|
450
474
|
}),
|
|
@@ -563,6 +587,7 @@ import { PostgresDatasourceIntrospectionProviderService } from "./services/datas
|
|
|
563
587
|
SchematicService,
|
|
564
588
|
MediaStorageProviderMetadataService,
|
|
565
589
|
MediaService,
|
|
590
|
+
MediaDownloadUrlService,
|
|
566
591
|
// MediaStorageProviderMetadataSeederService,
|
|
567
592
|
ModuleMetadataSeederService,
|
|
568
593
|
ModuleTestDataService,
|
|
@@ -647,6 +672,7 @@ import { PostgresDatasourceIntrospectionProviderService } from "./services/datas
|
|
|
647
672
|
SoftDeleteAwareEventSubscriber,
|
|
648
673
|
AccessTokenGuard,
|
|
649
674
|
ApiKeyGuard,
|
|
675
|
+
MediaSignedUrlGuard,
|
|
650
676
|
ApiKeyService,
|
|
651
677
|
ActiveSessionStorageService,
|
|
652
678
|
AuthenticationService,
|
|
@@ -665,6 +691,11 @@ import { PostgresDatasourceIntrospectionProviderService } from "./services/datas
|
|
|
665
691
|
ChatterQueueSubscriberRabbitmq,
|
|
666
692
|
ChatterQueuePublisherDatabase,
|
|
667
693
|
ChatterQueueSubscriberDatabase,
|
|
694
|
+
ChatterMentionNotificationEmailQueueHandler,
|
|
695
|
+
ChatterMentionNotificationEmailQueuePublisherRabbitmq,
|
|
696
|
+
ChatterMentionNotificationEmailQueueSubscriberRabbitmq,
|
|
697
|
+
ChatterMentionNotificationEmailQueuePublisherDatabase,
|
|
698
|
+
ChatterMentionNotificationEmailQueueSubscriberDatabase,
|
|
668
699
|
|
|
669
700
|
TestQueuePublisherDatabase,
|
|
670
701
|
TestQueueSubscriberDatabase,
|
|
@@ -674,6 +705,8 @@ import { PostgresDatasourceIntrospectionProviderService } from "./services/datas
|
|
|
674
705
|
ApiEmailQueueSubscriberRedis,
|
|
675
706
|
ChatterQueuePublisherRedis,
|
|
676
707
|
ChatterQueueSubscriberRedis,
|
|
708
|
+
ChatterMentionNotificationEmailQueuePublisherRedis,
|
|
709
|
+
ChatterMentionNotificationEmailQueueSubscriberRedis,
|
|
677
710
|
ComputedFieldEvaluationPublisherRedis,
|
|
678
711
|
ComputedFieldEvaluationSubscriberRedis,
|
|
679
712
|
GenerateCodePublisherRedis,
|
|
@@ -106,7 +106,7 @@ export class AuditSubscriber implements EntitySubscriberInterface {
|
|
|
106
106
|
|
|
107
107
|
const relationBefore = event.entity?.[AUDIT_BEFORE_SNAPSHOT] ?? null;
|
|
108
108
|
|
|
109
|
-
const relationAfter = await
|
|
109
|
+
const relationAfter = await event.queryRunner.manager.getRepository(event.metadata.target as any).findOne({
|
|
110
110
|
where: { id: entityId } as any,
|
|
111
111
|
relations: relations as any,
|
|
112
112
|
});
|