From 2aae4da3cd9d487cd48b86f632f6f318182ab778 Mon Sep 17 00:00:00 2001 From: Peter Maquiran Date: Thu, 15 Aug 2024 14:29:11 +0100 Subject: [PATCH] send all file --- package-lock.json | 14 ++--- package.json | 2 +- src/app/module/chat/domain/entity/message.ts | 13 ++--- ...essage-attachment-by-message-id.service.ts | 2 +- .../message-create-use-case.service.ts | 58 ++++++++++++------- .../shared/chat/messages/messages.page.html | 27 ++++++++- src/app/shared/chat/messages/messages.page.ts | 8 ++- src/app/utils/zod.ts | 51 ++++++++++------ src/app/utils/zodValidation.ts | 11 ++++ 9 files changed, 123 insertions(+), 63 deletions(-) create mode 100644 src/app/utils/zodValidation.ts diff --git a/package-lock.json b/package-lock.json index 8f698c4e9..dc8850157 100644 --- a/package-lock.json +++ b/package-lock.json @@ -200,7 +200,7 @@ "webpack": "^5.88.2", "wordcloud": "^1.1.2", "ws": "^7.5.9", - "zod": "^3.22.2", + "zod": "^3.23.8", "zone.js": "~0.11.4" }, "devDependencies": { @@ -44378,9 +44378,9 @@ } }, "node_modules/zod": { - "version": "3.22.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", - "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==", + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -78365,9 +78365,9 @@ "dev": true }, "zod": { - "version": "3.22.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", - "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==" + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" }, "zone.js": { "version": "0.11.4", diff --git a/package.json b/package.json index 969326f30..024216170 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,7 @@ "webpack": "^5.88.2", "wordcloud": "^1.1.2", "ws": "^7.5.9", - "zod": "^3.22.2", + "zod": "^3.23.8", "zone.js": "~0.11.4" }, "devDependencies": { diff --git a/src/app/module/chat/domain/entity/message.ts b/src/app/module/chat/domain/entity/message.ts index dee96cf08..5db0730c6 100644 --- a/src/app/module/chat/domain/entity/message.ts +++ b/src/app/module/chat/domain/entity/message.ts @@ -1,12 +1,13 @@ import { z } from "zod"; import { MessageAttachmentFileType, MessageAttachmentSource } from "../../data/dto/message/messageOutputDTO"; 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.string().optional(), - roomId: z.string().uuid(), - message: z.string(), + roomId: z.string(), + message: z.string().optional(), messageType: z.number(), canEdit: z.boolean(), oneShot: z.boolean(), @@ -22,15 +23,11 @@ const MessageEntitySchema = z.object({ attachments: z.array(z.object({ fileType: z.nativeEnum(MessageAttachmentFileType), source: z.nativeEnum(MessageAttachmentSource), - file: z.string().optional(), + file: base64Schema.optional(), fileName: z.string().optional(), applicationId: z.string().optional(), docId: z.string().optional() })), - attachmentsSource: z.array(z.object({ - file: z.string(), - id: z.string(), - })), }) type Message = z.infer; diff --git a/src/app/module/chat/domain/use-case/message-attachment-by-message-id.service.ts b/src/app/module/chat/domain/use-case/message-attachment-by-message-id.service.ts index aec4e5be0..e4867cdd2 100644 --- a/src/app/module/chat/domain/use-case/message-attachment-by-message-id.service.ts +++ b/src/app/module/chat/domain/use-case/message-attachment-by-message-id.service.ts @@ -48,6 +48,6 @@ export class MessageAttachmentByMessageIdUseCase { return dataUrl }) } - + } } diff --git a/src/app/module/chat/domain/use-case/message-create-use-case.service.ts b/src/app/module/chat/domain/use-case/message-create-use-case.service.ts index cdb7fd2b9..23bf7d370 100644 --- a/src/app/module/chat/domain/use-case/message-create-use-case.service.ts +++ b/src/app/module/chat/domain/use-case/message-create-use-case.service.ts @@ -1,12 +1,13 @@ 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 { 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 { InstanceId } from '../chat-service.service'; import { createDataURL } from 'src/app/utils/ToBase64'; import { DomSanitizer } from '@angular/platform-browser'; +import { zodSafeValidation } from 'src/app/utils/zodValidation'; const MessageInputUseCaseSchema = z.object({ memberId: z.number(), @@ -24,48 +25,61 @@ export class MessageCreateUseCaseService { constructor( private MessageRepositoryService: MessageRepositoryService, private AttachmentRepositoryService: AttachmentRepositoryService, - private sanitizer: DomSanitizer + private sanitizer: DomSanitizer, ) { } async execute(message: MessageEntity) { - message.sendAttemp++; + const validation = zodSafeValidation(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(message.hasAttachment) { + if(createMessageLocally.isOk()) { - for (const attachment of message.attachments) { + console.log('==========================',message); + if(message.hasAttachment) { - const createAttachmentLocally = this.AttachmentRepositoryService.create({ - $messageId: createMessageLocally.value.$id, - file: createDataURL(attachment.file, attachment.mimeType) - }) + for (const attachment of message.attachments) { + + 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()) { - console.log('sendToServer error', sendToServer.error) + if(validation.error.formErrors.fieldErrors.attachments) { + console.log(message.attachments) + console.error('invalid attachment', validation.error.formErrors.fieldErrors.attachments) } - - return sendToServer } - const result = await this.MessageRepositoryService.sendMessage(message) - return result } } diff --git a/src/app/shared/chat/messages/messages.page.html b/src/app/shared/chat/messages/messages.page.html index 7f0526dbd..aed02c601 100644 --- a/src/app/shared/chat/messages/messages.page.html +++ b/src/app/shared/chat/messages/messages.page.html @@ -56,7 +56,7 @@
-
+
{{ attachment.fileName}} @@ -66,10 +66,33 @@
-
+
+
+ +
+ +
+ + + + + + + + + + + {{ attachment.fileName}} +
+
diff --git a/src/app/shared/chat/messages/messages.page.ts b/src/app/shared/chat/messages/messages.page.ts index 3fb858feb..65439d8b8 100644 --- a/src/app/shared/chat/messages/messages.page.ts +++ b/src/app/shared/chat/messages/messages.page.ts @@ -137,6 +137,8 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy messageSendSubject: Subscription messages1: {[key: string]: MessageEntity[]} = {} + MessageAttachmentFileType = MessageAttachmentFileType + MessageAttachmentFileSource = MessageAttachmentSource constructor( public popoverController: PopoverController, @@ -875,7 +877,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy } message.attachments = [{ fileName: res.data.selected.Assunto, - source: MessageAttachmentSource.Webtrix, + source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Doc, applicationId: res.data.selected.ApplicationType, docId: res.data.selected.Id, @@ -927,7 +929,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy } message.attachments = [{ - file: file.value.base64String, + file: file.value.base64String.split(',')[1], fileName: "foto", source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Image, @@ -984,7 +986,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy } message.attachments = [{ - file: fileBase64.value, + file: fileBase64.value.split(',')[1], fileName: file.value.name, source: MessageAttachmentSource.Device, fileType: MessageAttachmentFileType.Doc, diff --git a/src/app/utils/zod.ts b/src/app/utils/zod.ts index 9ee0d209f..68f8d0170 100644 --- a/src/app/utils/zod.ts +++ b/src/app/utils/zod.ts @@ -23,28 +23,41 @@ export const zodDataUrlSchema = z.string().refine(value => zodDataUrlRegex.test( 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. - * @returns {void} - Logs the result of the validation. + * This schema checks if the string is valid Base64 and ensures that the first 20 characters + * do not contain a comma. * * @example - * validateDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC'); - * // Output: Valid data URL: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC - * - * validateDataUrl('invalid-url'); - * // Output: Validation error: [ ... ] + * ```typescript + * const validString = 'SGVsbG8sIHdvcmxkIQ=='; // Base64 for "Hello, world!" + * const invalidString = 'SGVsbG8sIHdvcmxkIQ,,=='; // Invalid due to commas + * + * console.log(base64Schema.safeParse(validString).success); // true + * console.log(base64Schema.safeParse(invalidString).success); // false + * ``` */ -const validateDataUrl = (url: string) => { - const result: any = zodDataUrlSchema.safeParse(url); - if (result.success) { - console.log('Valid data URL:', url); - } else { - console.error('Validation error:', result.error.errors); - } -}; +export const base64Schema = z.string().refine(value => { + // Regular expression for Base64 validation + const isBase64 = /^[A-Za-z0-9+/=]*$/.test(value) && (value.length % 4 === 0); + // Check if the first 20 characters do not contain a comma + return isBase64 && !value.substring(0, 20).includes(','); +}, { + message: 'Invalid Base64 string or comma found in the first 20 characters' +}); -// Test the schema -validateDataUrl('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDCAAAAC0BEMAAW9R3AAAAAElFTkSuQmCC'); -validateDataUrl('invalid-url'); \ No newline at end of file +/** + * Validates a given string against the Base64 schema. + * + * @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 + * ``` + */ diff --git a/src/app/utils/zodValidation.ts b/src/app/utils/zodValidation.ts new file mode 100644 index 000000000..1188360f3 --- /dev/null +++ b/src/app/utils/zodValidation.ts @@ -0,0 +1,11 @@ +import { err, ok } from 'neverthrow'; +import { ZodError, ZodSchema, z } from 'zod'; +export function zodSafeValidation(schema: ZodSchema, data) { + const validation = (schema as ZodSchema).safeParse(data) + + if(validation.success) { + return ok(validation.data) + } else { + return err((validation.error)) + } +}