mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-20 13:26:08 +00:00
send all file
This commit is contained in:
Generated
+7
-7
@@ -200,7 +200,7 @@
|
|||||||
"webpack": "^5.88.2",
|
"webpack": "^5.88.2",
|
||||||
"wordcloud": "^1.1.2",
|
"wordcloud": "^1.1.2",
|
||||||
"ws": "^7.5.9",
|
"ws": "^7.5.9",
|
||||||
"zod": "^3.22.2",
|
"zod": "^3.23.8",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -44378,9 +44378,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "3.22.2",
|
"version": "3.23.8",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||||
"integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==",
|
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
@@ -78365,9 +78365,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"zod": {
|
"zod": {
|
||||||
"version": "3.22.2",
|
"version": "3.23.8",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||||
"integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg=="
|
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
|
||||||
},
|
},
|
||||||
"zone.js": {
|
"zone.js": {
|
||||||
"version": "0.11.4",
|
"version": "0.11.4",
|
||||||
|
|||||||
+1
-1
@@ -217,7 +217,7 @@
|
|||||||
"webpack": "^5.88.2",
|
"webpack": "^5.88.2",
|
||||||
"wordcloud": "^1.1.2",
|
"wordcloud": "^1.1.2",
|
||||||
"ws": "^7.5.9",
|
"ws": "^7.5.9",
|
||||||
"zod": "^3.22.2",
|
"zod": "^3.23.8",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { MessageAttachmentFileType, MessageAttachmentSource } from "../../data/dto/message/messageOutputDTO";
|
import { MessageAttachmentFileType, MessageAttachmentSource } from "../../data/dto/message/messageOutputDTO";
|
||||||
import { SafeResourceUrl } from "@angular/platform-browser";
|
import { SafeResourceUrl } from "@angular/platform-browser";
|
||||||
|
import { base64Schema } from "src/app/utils/zod";
|
||||||
|
|
||||||
const MessageEntitySchema = z.object({
|
export const MessageEntitySchema = z.object({
|
||||||
$id: z.any().optional(),
|
$id: z.any().optional(),
|
||||||
id: z.string().optional(),
|
id: z.string().optional(),
|
||||||
roomId: z.string().uuid(),
|
roomId: z.string(),
|
||||||
message: z.string(),
|
message: z.string().optional(),
|
||||||
messageType: z.number(),
|
messageType: z.number(),
|
||||||
canEdit: z.boolean(),
|
canEdit: z.boolean(),
|
||||||
oneShot: z.boolean(),
|
oneShot: z.boolean(),
|
||||||
@@ -22,15 +23,11 @@ const MessageEntitySchema = z.object({
|
|||||||
attachments: z.array(z.object({
|
attachments: z.array(z.object({
|
||||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||||
source: z.nativeEnum(MessageAttachmentSource),
|
source: z.nativeEnum(MessageAttachmentSource),
|
||||||
file: z.string().optional(),
|
file: base64Schema.optional(),
|
||||||
fileName: z.string().optional(),
|
fileName: z.string().optional(),
|
||||||
applicationId: z.string().optional(),
|
applicationId: z.string().optional(),
|
||||||
docId: z.string().optional()
|
docId: z.string().optional()
|
||||||
})),
|
})),
|
||||||
attachmentsSource: z.array(z.object({
|
|
||||||
file: z.string(),
|
|
||||||
id: z.string(),
|
|
||||||
})),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
type Message = z.infer<typeof MessageEntitySchema>;
|
type Message = z.infer<typeof MessageEntitySchema>;
|
||||||
|
|||||||
@@ -48,6 +48,6 @@ export class MessageAttachmentByMessageIdUseCase {
|
|||||||
return dataUrl
|
return dataUrl
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { MessageEntity } from '../entity/message';
|
import { MessageEntity, MessageEntitySchema, } from '../entity/message';
|
||||||
import { MessageRepositoryService } from "src/app/module/chat/data/repository/message-respository.service"
|
import { MessageRepositoryService } from "src/app/module/chat/data/repository/message-respository.service"
|
||||||
import { AttachmentRepositoryService } from "src/app/module/chat/data/repository/attachment-repository.service"
|
import { AttachmentRepositoryService } from "src/app/module/chat/data/repository/attachment-repository.service"
|
||||||
import { z } from 'zod';
|
import { z, ZodError } from 'zod';
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { InstanceId } from '../chat-service.service';
|
import { InstanceId } from '../chat-service.service';
|
||||||
import { createDataURL } from 'src/app/utils/ToBase64';
|
import { createDataURL } from 'src/app/utils/ToBase64';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
|
import { zodSafeValidation } from 'src/app/utils/zodValidation';
|
||||||
|
|
||||||
const MessageInputUseCaseSchema = z.object({
|
const MessageInputUseCaseSchema = z.object({
|
||||||
memberId: z.number(),
|
memberId: z.number(),
|
||||||
@@ -24,48 +25,61 @@ export class MessageCreateUseCaseService {
|
|||||||
constructor(
|
constructor(
|
||||||
private MessageRepositoryService: MessageRepositoryService,
|
private MessageRepositoryService: MessageRepositoryService,
|
||||||
private AttachmentRepositoryService: AttachmentRepositoryService,
|
private AttachmentRepositoryService: AttachmentRepositoryService,
|
||||||
private sanitizer: DomSanitizer
|
private sanitizer: DomSanitizer,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
|
||||||
async execute(message: MessageEntity) {
|
async execute(message: MessageEntity) {
|
||||||
|
|
||||||
message.sendAttemp++;
|
const validation = zodSafeValidation<MessageEntity>(MessageEntitySchema, message)
|
||||||
|
|
||||||
message.requestId = InstanceId +'@'+ uuidv4();
|
if(validation.isOk()) {
|
||||||
|
message.sendAttemp++;
|
||||||
|
|
||||||
const createMessageLocally = await this.MessageRepositoryService.createMessageLocally(message)
|
message.requestId = InstanceId +'@'+ uuidv4();
|
||||||
|
|
||||||
if(createMessageLocally.isOk()) {
|
const createMessageLocally = await this.MessageRepositoryService.createMessageLocally(message)
|
||||||
|
|
||||||
console.log('==========================',message);
|
if(createMessageLocally.isOk()) {
|
||||||
if(message.hasAttachment) {
|
|
||||||
|
|
||||||
for (const attachment of message.attachments) {
|
console.log('==========================',message);
|
||||||
|
if(message.hasAttachment) {
|
||||||
|
|
||||||
const createAttachmentLocally = this.AttachmentRepositoryService.create({
|
for (const attachment of message.attachments) {
|
||||||
$messageId: createMessageLocally.value.$id,
|
|
||||||
file: createDataURL(attachment.file, attachment.mimeType)
|
const createAttachmentLocally = this.AttachmentRepositoryService.create({
|
||||||
})
|
$messageId: createMessageLocally.value.$id,
|
||||||
|
file: createDataURL(attachment.file, attachment.mimeType)
|
||||||
|
})
|
||||||
|
|
||||||
|
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
|
||||||
|
}
|
||||||
|
|
||||||
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sendToServer = await this.MessageRepositoryService.sendMessage(message)
|
||||||
|
|
||||||
|
|
||||||
|
if(!sendToServer.isOk()) {
|
||||||
|
console.log('sendToServer error', sendToServer.error)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return sendToServer
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendToServer = await this.MessageRepositoryService.sendMessage(message)
|
const result = await this.MessageRepositoryService.sendMessage(message)
|
||||||
|
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
|
||||||
if(!sendToServer.isOk()) {
|
if(validation.error.formErrors.fieldErrors.attachments) {
|
||||||
console.log('sendToServer error', sendToServer.error)
|
console.log(message.attachments)
|
||||||
|
console.error('invalid attachment', validation.error.formErrors.fieldErrors.attachments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return sendToServer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.MessageRepositoryService.sendMessage(message)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let attachment of message.attachments; let i = index">
|
<div *ngFor="let attachment of message.attachments; let i = index">
|
||||||
<div *ngIf="attachment.fileType == 1">
|
<div *ngIf="attachment.source == MessageAttachmentFileSource.Webtrix">
|
||||||
|
|
||||||
<ion-icon src="assets/icon/webtrix.svg" class="file-icon font-25"></ion-icon>
|
<ion-icon src="assets/icon/webtrix.svg" class="file-icon font-25"></ion-icon>
|
||||||
<ion-label>{{ attachment.fileName}}</ion-label>
|
<ion-label>{{ attachment.fileName}}</ion-label>
|
||||||
@@ -66,10 +66,33 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="attachment.fileType == 2">
|
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Image">
|
||||||
<img [src]="attachment.safeFile">
|
<img [src]="attachment.safeFile">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Audio">
|
||||||
|
<audio controls>
|
||||||
|
<source [src]="attachment.safeFile" >
|
||||||
|
Your browser does not support the audio element.
|
||||||
|
</audio>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="attachment.fileType == MessageAttachmentFileType.Doc">
|
||||||
|
<fa-icon *ngIf="attachment.mimeType == 'application/pdf'" icon="file-pdf" class="pdf-icon"></fa-icon>
|
||||||
|
<fa-icon *ngIf="attachment.mimeType == 'application/word'" icon="file-word" class="word-icon">
|
||||||
|
</fa-icon>
|
||||||
|
<fa-icon *ngIf="attachment.mimeType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'" icon="file-word" class="word-icon"></fa-icon>
|
||||||
|
<fa-icon
|
||||||
|
*ngIf="attachment.mimeType == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"
|
||||||
|
icon="file-word" class="excel-icon"></fa-icon>
|
||||||
|
<ion-icon *ngIf="attachment.mimeType == 'application/webtrix'" src="assets/icon/webtrix.svg">
|
||||||
|
</ion-icon>
|
||||||
|
<ion-icon *ngIf="attachment.mimeType == 'application/meeting'" src="assets/icon/webtrix.svg">
|
||||||
|
</ion-icon>
|
||||||
|
|
||||||
|
<ion-label>{{ attachment.fileName}}</ion-label>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -137,6 +137,8 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
messageSendSubject: Subscription
|
messageSendSubject: Subscription
|
||||||
|
|
||||||
messages1: {[key: string]: MessageEntity[]} = {}
|
messages1: {[key: string]: MessageEntity[]} = {}
|
||||||
|
MessageAttachmentFileType = MessageAttachmentFileType
|
||||||
|
MessageAttachmentFileSource = MessageAttachmentSource
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public popoverController: PopoverController,
|
public popoverController: PopoverController,
|
||||||
@@ -875,7 +877,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
}
|
}
|
||||||
message.attachments = [{
|
message.attachments = [{
|
||||||
fileName: res.data.selected.Assunto,
|
fileName: res.data.selected.Assunto,
|
||||||
source: MessageAttachmentSource.Webtrix,
|
source: MessageAttachmentSource.Device,
|
||||||
fileType: MessageAttachmentFileType.Doc,
|
fileType: MessageAttachmentFileType.Doc,
|
||||||
applicationId: res.data.selected.ApplicationType,
|
applicationId: res.data.selected.ApplicationType,
|
||||||
docId: res.data.selected.Id,
|
docId: res.data.selected.Id,
|
||||||
@@ -927,7 +929,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
message.attachments = [{
|
message.attachments = [{
|
||||||
file: file.value.base64String,
|
file: file.value.base64String.split(',')[1],
|
||||||
fileName: "foto",
|
fileName: "foto",
|
||||||
source: MessageAttachmentSource.Device,
|
source: MessageAttachmentSource.Device,
|
||||||
fileType: MessageAttachmentFileType.Image,
|
fileType: MessageAttachmentFileType.Image,
|
||||||
@@ -984,7 +986,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
message.attachments = [{
|
message.attachments = [{
|
||||||
file: fileBase64.value,
|
file: fileBase64.value.split(',')[1],
|
||||||
fileName: file.value.name,
|
fileName: file.value.name,
|
||||||
source: MessageAttachmentSource.Device,
|
source: MessageAttachmentSource.Device,
|
||||||
fileType: MessageAttachmentFileType.Doc,
|
fileType: MessageAttachmentFileType.Doc,
|
||||||
|
|||||||
+32
-19
@@ -23,28 +23,41 @@ export const zodDataUrlSchema = z.string().refine(value => zodDataUrlRegex.test(
|
|||||||
message: 'Invalid data URL',
|
message: 'Invalid data URL',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//===============================================================================
|
||||||
/**
|
/**
|
||||||
* Validates if a string is a valid data URL.
|
* A schema for validating Base64 encoded strings.
|
||||||
*
|
*
|
||||||
* @param url - The string to validate as a data URL.
|
* This schema checks if the string is valid Base64 and ensures that the first 20 characters
|
||||||
* @returns {void} - Logs the result of the validation.
|
* do not contain a comma.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* validateDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC');
|
* ```typescript
|
||||||
* // Output: Valid data URL: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC
|
* const validString = 'SGVsbG8sIHdvcmxkIQ=='; // Base64 for "Hello, world!"
|
||||||
*
|
* const invalidString = 'SGVsbG8sIHdvcmxkIQ,,=='; // Invalid due to commas
|
||||||
* validateDataUrl('invalid-url');
|
*
|
||||||
* // Output: Validation error: [ ... ]
|
* console.log(base64Schema.safeParse(validString).success); // true
|
||||||
|
* console.log(base64Schema.safeParse(invalidString).success); // false
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
const validateDataUrl = (url: string) => {
|
export const base64Schema = z.string().refine(value => {
|
||||||
const result: any = zodDataUrlSchema.safeParse(url);
|
// Regular expression for Base64 validation
|
||||||
if (result.success) {
|
const isBase64 = /^[A-Za-z0-9+/=]*$/.test(value) && (value.length % 4 === 0);
|
||||||
console.log('Valid data URL:', url);
|
// Check if the first 20 characters do not contain a comma
|
||||||
} else {
|
return isBase64 && !value.substring(0, 20).includes(',');
|
||||||
console.error('Validation error:', result.error.errors);
|
}, {
|
||||||
}
|
message: 'Invalid Base64 string or comma found in the first 20 characters'
|
||||||
};
|
});
|
||||||
|
|
||||||
// Test the schema
|
/**
|
||||||
validateDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC');
|
* Validates a given string against the Base64 schema.
|
||||||
validateDataUrl('invalid-url');
|
*
|
||||||
|
* @param input - The string to validate.
|
||||||
|
* @returns `true` if the input is valid according to the schema, `false` otherwise.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* console.log(validateInput('SGVsbG8sIHdvcmxkIQ==')); // true
|
||||||
|
* console.log(validateInput('SGVsbG8sIHdvcmxkIQ,,==')); // false
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { err, ok } from 'neverthrow';
|
||||||
|
import { ZodError, ZodSchema, z } from 'zod';
|
||||||
|
export function zodSafeValidation<T>(schema: ZodSchema, data) {
|
||||||
|
const validation = (schema as ZodSchema<T>).safeParse(data)
|
||||||
|
|
||||||
|
if(validation.success) {
|
||||||
|
return ok(validation.data)
|
||||||
|
} else {
|
||||||
|
return err((validation.error))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user