rez_core 3.1.198 → 3.1.200
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/module/meta/controller/media.controller.d.ts +3 -0
- package/dist/module/meta/controller/media.controller.js +15 -0
- package/dist/module/meta/controller/media.controller.js.map +1 -1
- package/dist/module/meta/entity/entity-master.entity.d.ts +2 -0
- package/dist/module/meta/entity/entity-master.entity.js +8 -0
- package/dist/module/meta/entity/entity-master.entity.js.map +1 -1
- package/dist/module/meta/service/media-data.service.d.ts +5 -1
- package/dist/module/meta/service/media-data.service.js +59 -2
- package/dist/module/meta/service/media-data.service.js.map +1 -1
- package/dist/module/notification/service/otp.service.js +8 -2
- package/dist/module/notification/service/otp.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/meta/controller/media.controller.ts +10 -0
- package/src/module/meta/entity/entity-master.entity.ts +6 -0
- package/src/module/meta/service/media-data.service.ts +92 -1
- package/src/module/notification/service/otp.service.ts +9 -2
package/package.json
CHANGED
|
@@ -79,4 +79,14 @@ export class MediaController {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
|
|
83
|
+
@Post('generateUploadPath')
|
|
84
|
+
async generateUploadPath(@Req() req: Request & { user: any }, @Query('mapped_entity_type') mapped_entity_type: string,
|
|
85
|
+
@Query('mapped_entity_id') mapped_entity_id?: number,
|
|
86
|
+
@Query('parent_id') parent_id?: number,
|
|
87
|
+
@Query('parent_type') parent_type?: string,
|
|
88
|
+
) {
|
|
89
|
+
const loggedInUser = req.user.userData;
|
|
90
|
+
return this.mediaDataService.buildUploadPathGeneric(mapped_entity_type, loggedInUser, mapped_entity_id,parent_id, parent_type)
|
|
91
|
+
}
|
|
82
92
|
}
|
|
@@ -75,4 +75,10 @@ export class EntityMaster extends BaseEntity {
|
|
|
75
75
|
|
|
76
76
|
@Column({ name: 'is_workflow', nullable: true })
|
|
77
77
|
is_workflow: boolean;
|
|
78
|
+
|
|
79
|
+
@Column({ name: 'doc_upload_path', nullable: true, length:50 })
|
|
80
|
+
doc_upload_path: string;
|
|
81
|
+
|
|
82
|
+
@Column({name: 'overwrite_path', type: 'tinyint', nullable: true})
|
|
83
|
+
overwrite_path: number;
|
|
78
84
|
}
|
|
@@ -9,12 +9,16 @@ import {
|
|
|
9
9
|
STATUS_PENDING,
|
|
10
10
|
} from '../../../constant/global.constant';
|
|
11
11
|
import { v4 as uuidv4 } from 'uuid';
|
|
12
|
+
import { OrganizationService } from '../../enterprise/service/organization.service';
|
|
13
|
+
import { EntityMasterService } from './entity-master.service';
|
|
14
|
+
import { DataSource } from 'typeorm';
|
|
12
15
|
|
|
13
16
|
@Injectable()
|
|
14
17
|
export class MediaDataService extends EntityServiceImpl {
|
|
15
18
|
constructor(
|
|
16
19
|
private readonly configService: ConfigService,
|
|
17
20
|
private readonly mediaRepository: MediaDataRepository,
|
|
21
|
+
private dataSource: DataSource,
|
|
18
22
|
) {
|
|
19
23
|
super();
|
|
20
24
|
}
|
|
@@ -44,6 +48,8 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
44
48
|
const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
|
|
45
49
|
|
|
46
50
|
const id = uuidv4();
|
|
51
|
+
|
|
52
|
+
//TODO:
|
|
47
53
|
const s3Key = `uploads/${id}.${ext}`;
|
|
48
54
|
|
|
49
55
|
const uploadUrl = await this.s3.getSignedUrlPromise('putObject', {
|
|
@@ -140,10 +146,95 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
140
146
|
Key: mediaData.media_url,
|
|
141
147
|
Expires: Number(expiresIn) || 60 * 5,
|
|
142
148
|
});
|
|
143
|
-
return { signedUrl, fileName: mediaData.file_name, id: mediaData.id, size: fileSize};
|
|
149
|
+
return { signedUrl, fileName: mediaData.file_name, id: mediaData.id, size: fileSize };
|
|
144
150
|
} catch (error) {
|
|
145
151
|
console.error('Error generating signed URL for media:', error);
|
|
146
152
|
throw new Error('Failed to generate signed URL');
|
|
147
153
|
}
|
|
148
154
|
}
|
|
155
|
+
|
|
156
|
+
public async buildUploadPathGeneric(
|
|
157
|
+
mappedEntityType: string,
|
|
158
|
+
loggedInUser,
|
|
159
|
+
mappedEntityId?: number,
|
|
160
|
+
parentId?: number,
|
|
161
|
+
parentType?: string,
|
|
162
|
+
) {
|
|
163
|
+
// 1️⃣ Fetch entity metadata
|
|
164
|
+
const entityMaster = await this.entityMasterService.getEntityData(mappedEntityType, loggedInUser);
|
|
165
|
+
if (!entityMaster) {
|
|
166
|
+
throw new Error(`Entity master not found for ${mappedEntityType}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let pathTemplate = entityMaster.doc_upload_path ?? '';
|
|
170
|
+
const entityOverwrite = entityMaster.overwrite_path ?? 0;
|
|
171
|
+
|
|
172
|
+
if (!pathTemplate) {
|
|
173
|
+
throw new Error(`doc_upload_path not defined for ${mappedEntityType}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// 2️⃣ Prepare replacement map
|
|
177
|
+
const replacements: Record<string, string | null> = {};
|
|
178
|
+
|
|
179
|
+
// --- ORG ---
|
|
180
|
+
let organizationData = await this.dataSource.query('SELECT * FROM sso_organization WHERE id = ?', [loggedInUser.organization_id]);
|
|
181
|
+
replacements['org_code'] = organizationData[0].code;
|
|
182
|
+
|
|
183
|
+
// --- LEVEL CODE ---
|
|
184
|
+
// Determine which entity to use for level_code
|
|
185
|
+
const levelEntityId = entityOverwrite ? mappedEntityId : loggedInUser.level_id;
|
|
186
|
+
const levelEntityData = await super.getEntityData(loggedInUser.level_type, levelEntityId, loggedInUser);
|
|
187
|
+
if (levelEntityData?.code) {
|
|
188
|
+
replacements['level_code'] = levelEntityData.code; // universal alias
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// --- Dynamic variables inside path ---
|
|
192
|
+
const matches = pathTemplate.match(/\$\{(\w+)\}/g) || [];
|
|
193
|
+
|
|
194
|
+
for (const variable of matches) {
|
|
195
|
+
const key = variable.replace(/\$\{|\}/g, '');
|
|
196
|
+
if (replacements[key]) continue; // already resolved
|
|
197
|
+
|
|
198
|
+
if (key === 'org_code') continue; // already set
|
|
199
|
+
if (key.endsWith('_code')) {
|
|
200
|
+
// derive entity type dynamically
|
|
201
|
+
const entityType = key.replace('_code', '').toUpperCase();
|
|
202
|
+
|
|
203
|
+
let entityId: number | undefined;
|
|
204
|
+
if (parentType?.toUpperCase() === entityType && parentId) {
|
|
205
|
+
entityId = parentId;
|
|
206
|
+
} else {
|
|
207
|
+
entityId = mappedEntityId;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Generic lookup
|
|
211
|
+
if (entityId) {
|
|
212
|
+
const entityData = await super.getEntityData(entityType, entityId, loggedInUser);
|
|
213
|
+
replacements[key] = entityData?.code ?? null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// --- ORG special case ---
|
|
219
|
+
// If ORG level & overwrite = 0 → remove level_code variable
|
|
220
|
+
if (loggedInUser.level_type === 'ORG' && entityOverwrite === 0) {
|
|
221
|
+
replacements['level_code'] = null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 3️⃣ Final substitution and cleanup
|
|
225
|
+
if (pathTemplate) {
|
|
226
|
+
const finalPath = this.resolveUploadPath(pathTemplate, replacements);
|
|
227
|
+
return finalPath;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Replace placeholders with actual values, remove missing variables
|
|
234
|
+
*/
|
|
235
|
+
private resolveUploadPath(template: string, replacements: Record<string, string | null>) {
|
|
236
|
+
let path = template;
|
|
237
|
+
path = path.replace(/\$\{(\w+)\}/g, (_, key) => replacements[key] || '');
|
|
238
|
+
return path.replace(/\/+/g, '/').replace(/\/$/, '');
|
|
239
|
+
}
|
|
149
240
|
}
|
|
@@ -70,12 +70,19 @@ export class OtpService {
|
|
|
70
70
|
// Find OTP entity by ID
|
|
71
71
|
const otpEntity = await this.findByOtpId(otp_id);
|
|
72
72
|
if (!otpEntity) {
|
|
73
|
-
throw new BadRequestException('OTP not found!');
|
|
73
|
+
// throw new BadRequestException('OTP not found!');
|
|
74
|
+
return {
|
|
75
|
+
sucess: false,
|
|
76
|
+
message: 'OTP not found!',
|
|
77
|
+
};
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
// Validate the identifier against the OTP entity
|
|
77
81
|
if (otpEntity.identifier !== identifier) {
|
|
78
|
-
|
|
82
|
+
return {
|
|
83
|
+
sucess: false,
|
|
84
|
+
message: 'Invalid OTP identifier!',
|
|
85
|
+
};
|
|
79
86
|
}
|
|
80
87
|
|
|
81
88
|
// OTP validation logic
|