From dea358661e641a589f04f00484311b9bf4bd65ec Mon Sep 17 00:00:00 2001 From: Piotr Date: Fri, 26 Apr 2024 09:19:20 +0200 Subject: [PATCH 1/5] Receive Get - support uuid & id_account --- Credentials/controllers/receiving/Get.ts | 31 +++++++++++++++------ _common/models/ReceivingCredential.model.ts | 26 +++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/Credentials/controllers/receiving/Get.ts b/Credentials/controllers/receiving/Get.ts index e700de0..f8db653 100644 --- a/Credentials/controllers/receiving/Get.ts +++ b/Credentials/controllers/receiving/Get.ts @@ -1,28 +1,41 @@ -import { checkIfPositiveIntegerStringOrNumber } from "../../../_common/utils/Request.utils"; +import { checkIfPositiveIntegerStringOrNumber, checkIfTypeIsString } from "../../../_common/utils/Request.utils"; import { HttpRequest } from "@azure/functions"; import ReceivingCredential from '../../../_common/models/ReceivingCredential.model'; import { checkReceivingRequestQueryParamsForGet } from '../../../_common/utils/ReceivingRequest.utils'; export const getReceive = async (req: HttpRequest) => { - const { id_account } = req.query; + const { id_account, uuid } = req.query; + + let response_from_db try { - // Chack body params - checkReceivingRequestQueryParamsForGet(id_account); + if (uuid) { + // Check if uuid is a string + checkIfTypeIsString(uuid, 'uuid'); - checkIfPositiveIntegerStringOrNumber(id_account, 'id_account'); + // Check if row with id_account already exists + response_from_db = await ReceivingCredential.getUUID(uuid); + } + else { + // Chack body params + checkReceivingRequestQueryParamsForGet(id_account); - // Check if row with id_account already exists - const response_from_db = await ReceivingCredential.get(Number(id_account)); + checkIfPositiveIntegerStringOrNumber(id_account, 'id_account'); + + // Check if row with id_account already exists + response_from_db = await ReceivingCredential.get(Number(id_account)); + } if (!response_from_db) { + const property_name = uuid ? 'uuid' : 'id_account'; + return { status: 404, body: { status: 'Not found', - field_name: 'id_account', - description: 'Resource with the provided id_account does not exist.' + field_name: property_name, + description: `Resource with the provided ${property_name} does not exist.` }, headers: { 'Content-Type': 'application/json' diff --git a/_common/models/ReceivingCredential.model.ts b/_common/models/ReceivingCredential.model.ts index d0fc1e1..f54ead2 100644 --- a/_common/models/ReceivingCredential.model.ts +++ b/_common/models/ReceivingCredential.model.ts @@ -71,6 +71,32 @@ export default class ReceivingCredential { return results.entries[0]; } + /** + * Get object + * @param {string} uuid - Azure Tenant ID + * @return {object} - Return object from DB + **/ + static getUUID = async (uuid: string) => { + // Define the query + const query = new AzureStorage.TableQuery().where('uuid eq ?', uuid); + + // Get objects from DB + const results: any = await new Promise((resolve, reject) => { + this.table_service.queryEntities(this.table_name, query, null, (error, result) => { + if (error) { + ErrorLogs.insert({}, `Problem when trying to get object: ${error}`, '--- Get Receiving Credentials ---'); + + reject(error); + } + else { + resolve(result); + } + }); + }); + + return results.entries[0]; + } + /** * Retrieves all receiving credentials from the database. * @returns {Promise>} A promise that resolves to an array of receiving credentials. From bb382c8aa2c7564ff893c11ea39daa17613877fb Mon Sep 17 00:00:00 2001 From: Piotr Date: Fri, 26 Apr 2024 11:00:39 +0200 Subject: [PATCH 2/5] Unique uuid for Receiving Credentials + Global ErrorLog --- Credentials/controllers/receiving/Create.ts | 10 ++++++++-- Credentials/index.ts | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Credentials/controllers/receiving/Create.ts b/Credentials/controllers/receiving/Create.ts index 6dd7e58..281df96 100644 --- a/Credentials/controllers/receiving/Create.ts +++ b/Credentials/controllers/receiving/Create.ts @@ -1,4 +1,4 @@ -import { checkIfRequestBodyExists, checkIfPositiveIntegerNumber, checkIfTypeIsString } from "../../../_common/utils/Request.utils"; +import { checkIfPositiveIntegerNumber, checkIfRequestBodyExists, checkIfTypeIsString } from "../../../_common/utils/Request.utils"; import { HttpRequest } from "@azure/functions"; import ReceivingCredential from '../../../_common/models/ReceivingCredential.model'; @@ -21,11 +21,17 @@ export const createReceive = async (req: HttpRequest) => { checkIfTypeIsString(username, 'username'); // Check if row with id_account already exists - const response_from_db = await ReceivingCredential.get(id_account); + let response_from_db = await ReceivingCredential.get(id_account); // If exists throw error 409 - Conflict throwIfDatabaseResourceExists(response_from_db, 'id_account'); + // Check if row with uuid already exists + response_from_db = await ReceivingCredential.getUUID(uuid); + + // If exists throw error 409 - Conflict + throwIfDatabaseResourceExists(response_from_db, 'uuid'); + await ReceivingCredential.create(id_account, uuid, username); return { diff --git a/Credentials/index.ts b/Credentials/index.ts index 39cba45..f5803f8 100644 --- a/Credentials/index.ts +++ b/Credentials/index.ts @@ -1,5 +1,6 @@ import { AzureFunction, Context, HttpRequest } from "@azure/functions" +import { ErrorLogs } from "../_common/models/ErrorLogs.model"; import { create } from "./controllers/fetching/Create"; import { createReceive } from "./controllers/receiving/Create"; import { get } from "./controllers/fetching/Get"; @@ -86,6 +87,12 @@ const httpTrigger: AzureFunction = async function (context: Context, req: HttpRe 'Content-Type': 'application/json' } }; + + ErrorLogs.insert( + { error: error, req: req }, + 'Unexpected error occurred.', + '--- Internal error ---' + ); } }; From aae0584753a70989627df103f8f7756855f6341a Mon Sep 17 00:00:00 2001 From: Piotr Date: Fri, 26 Apr 2024 11:11:04 +0200 Subject: [PATCH 3/5] Create Receiving Credentials - unique username validation --- Credentials/controllers/receiving/Create.ts | 6 +++++ _common/models/ReceivingCredential.model.ts | 26 +++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Credentials/controllers/receiving/Create.ts b/Credentials/controllers/receiving/Create.ts index 281df96..e1ff0df 100644 --- a/Credentials/controllers/receiving/Create.ts +++ b/Credentials/controllers/receiving/Create.ts @@ -32,6 +32,12 @@ export const createReceive = async (req: HttpRequest) => { // If exists throw error 409 - Conflict throwIfDatabaseResourceExists(response_from_db, 'uuid'); + // Check if row with uuid already exists + response_from_db = await ReceivingCredential.getUsername(username); + + // If exists throw error 409 - Conflict + throwIfDatabaseResourceExists(response_from_db, 'username'); + await ReceivingCredential.create(id_account, uuid, username); return { diff --git a/_common/models/ReceivingCredential.model.ts b/_common/models/ReceivingCredential.model.ts index f54ead2..c97226a 100644 --- a/_common/models/ReceivingCredential.model.ts +++ b/_common/models/ReceivingCredential.model.ts @@ -97,6 +97,32 @@ export default class ReceivingCredential { return results.entries[0]; } + /** + * Get object + * @param {string} username - Client username + * @return {object} - Return object from DB + **/ + static getUsername = async (username: string) => { + // Define the query + const query = new AzureStorage.TableQuery().where('username eq ?', username); + + // Get objects from DB + const results: any = await new Promise((resolve, reject) => { + this.table_service.queryEntities(this.table_name, query, null, (error, result) => { + if (error) { + ErrorLogs.insert({}, `Problem when trying to get object: ${error}`, '--- Get Receiving Credentials ---'); + + reject(error); + } + else { + resolve(result); + } + }); + }); + + return results.entries[0]; + } + /** * Retrieves all receiving credentials from the database. * @returns {Promise>} A promise that resolves to an array of receiving credentials. From 4e62d0323a4b5ac39db64541d2bd851c68a1556d Mon Sep 17 00:00:00 2001 From: Piotr Date: Fri, 26 Apr 2024 13:13:38 +0200 Subject: [PATCH 4/5] Receiving update -> validation if unique username & uuid --- Credentials/controllers/receiving/Update.ts | 10 ++++++-- _common/models/ReceivingCredential.model.ts | 28 +++++++++++++++++++++ _common/utils/DatabaseResponse.utils.ts | 5 ++++ _common/utils/ReceivingRequest.utils.ts | 18 +++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Credentials/controllers/receiving/Update.ts b/Credentials/controllers/receiving/Update.ts index 71ea8ca..8046d2b 100644 --- a/Credentials/controllers/receiving/Update.ts +++ b/Credentials/controllers/receiving/Update.ts @@ -1,8 +1,8 @@ -import { checkIfRequestBodyExists, checkIfPositiveIntegerNumber, checkIfTypeIsString } from "../../../_common/utils/Request.utils"; +import { checkIfPositiveIntegerNumber, checkIfRequestBodyExists, checkIfTypeIsString } from "../../../_common/utils/Request.utils"; +import { checkReceivingRequestBodyParamsForCreateOrUpdate, throwIfDuplicateObject } from "../../../_common/utils/ReceivingRequest.utils"; import { HttpRequest } from "@azure/functions"; import ReceivingCredential from '../../../_common/models/ReceivingCredential.model'; -import { checkReceivingRequestBodyParamsForCreateOrUpdate } from "../../../_common/utils/ReceivingRequest.utils"; export const updateReceive = async (req: HttpRequest) => { // Check if request body exists @@ -39,6 +39,12 @@ export const updateReceive = async (req: HttpRequest) => { } } else { + // Check if username or uuid already exists + const response = await ReceivingCredential.getByUUIDOrUsername(uuid, username); + + throwIfDuplicateObject(response, 'uuid', uuid, id_account); + throwIfDuplicateObject(response, 'username', username, id_account); + // Update object properties response_from_db.username = username; response_from_db.uuid = uuid; diff --git a/_common/models/ReceivingCredential.model.ts b/_common/models/ReceivingCredential.model.ts index c97226a..1cc0dba 100644 --- a/_common/models/ReceivingCredential.model.ts +++ b/_common/models/ReceivingCredential.model.ts @@ -71,6 +71,34 @@ export default class ReceivingCredential { return results.entries[0]; } + /** + * Get object by UUID or username. + * @param {string} uuid - The UUID of the credential. + * @param {string} username - The username associated with the credential. + * @returns {object} - Return object from DB + **/ + static getByUUIDOrUsername = async (uuid: string, username: string) => { + // Define the query + const query = new AzureStorage.TableQuery().where('uuid eq ? or username eq ?', uuid, username); + // Get objects from DB + const results: any = await new Promise((resolve, reject) => { + this.table_service.queryEntities(this.table_name, query, null, (error, result) => { + if (error) { + ErrorLogs.insert({}, `Problem when trying to get object: ${error}`, '--- Get Receiving Credentials ---'); + reject(error); + } + else { + resolve(result); + } + }); + }); + return results.entries.map(entry => ({ + uuid: entry.uuid._, + username: entry.username._, + id_account: entry.id_account._, + })); + } + /** * Get object * @param {string} uuid - Azure Tenant ID diff --git a/_common/utils/DatabaseResponse.utils.ts b/_common/utils/DatabaseResponse.utils.ts index 4fafaf0..9e5b911 100644 --- a/_common/utils/DatabaseResponse.utils.ts +++ b/_common/utils/DatabaseResponse.utils.ts @@ -1,3 +1,5 @@ +import { error } from "console"; + /** * Throws an error if a database resource already exists. * @param object - The object to check if it exists. @@ -8,8 +10,10 @@ export const throwIfDatabaseResourceExists = (object: any, file_name: string) => if (object) { throw { status: 409, + error: true, body: { status: 'Conflict', + file_name: file_name, description: `Resource with the provided ${file_name} already exists.` }, headers: { @@ -29,6 +33,7 @@ export const throwIfDatabaseResourceNotExists = (object: any, file_name: string) if (!object) { throw { status: 404, + error: true, body: { status: 'Not Found', description: `Resource with the provided ${file_name} does not exists.` diff --git a/_common/utils/ReceivingRequest.utils.ts b/_common/utils/ReceivingRequest.utils.ts index 2202111..bbaf74e 100644 --- a/_common/utils/ReceivingRequest.utils.ts +++ b/_common/utils/ReceivingRequest.utils.ts @@ -44,3 +44,21 @@ export const checkReceivingRequestBodyParamsForCreateOrUpdate = (uuid: string, u }; } } + +export const throwIfDuplicateObject = (response: any[], field: string, value: string | number, id_account: number) => { + const duplicateObject = response.find(obj => obj[field] === value && obj.id_account !== id_account); + + if (duplicateObject) { + throw { + status: 400, + body: { + status: 'Bad Request', + field_name: field, + description: `An object with the same ${field} but a different id_account already exists.` + }, + headers: { + 'Content-Type': 'application/json' + } + } + } +} From ed8e1cac2181cf47bd97cc5125994ca940c22a20 Mon Sep 17 00:00:00 2001 From: Piotr Date: Fri, 26 Apr 2024 14:19:24 +0200 Subject: [PATCH 5/5] file_name => field_name --- _common/utils/DatabaseResponse.utils.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/_common/utils/DatabaseResponse.utils.ts b/_common/utils/DatabaseResponse.utils.ts index 9e5b911..a20c30b 100644 --- a/_common/utils/DatabaseResponse.utils.ts +++ b/_common/utils/DatabaseResponse.utils.ts @@ -3,18 +3,18 @@ import { error } from "console"; /** * Throws an error if a database resource already exists. * @param object - The object to check if it exists. - * @param file_name - The name of the file associated with the resource. + * @param field_name - The name of the field associated with the resource. * @throws {Object} - An error object with status 409 and a body containing the conflict details. */ -export const throwIfDatabaseResourceExists = (object: any, file_name: string) => { +export const throwIfDatabaseResourceExists = (object: any, field_name: string) => { if (object) { throw { status: 409, error: true, body: { status: 'Conflict', - file_name: file_name, - description: `Resource with the provided ${file_name} already exists.` + field_name: field_name, + description: `Resource with the provided ${field_name} already exists.` }, headers: { 'Content-Type': 'application/json' @@ -26,17 +26,17 @@ export const throwIfDatabaseResourceExists = (object: any, file_name: string) => /** * Throws an error if the database resource does not exist. * @param object - The object to check if it exists. - * @param file_name - The name of the file associated with the resource. + * @param field_name - The name of the field associated with the resource. * @throws {Object} - An error object with status 404 and a description of the error. */ -export const throwIfDatabaseResourceNotExists = (object: any, file_name: string) => { +export const throwIfDatabaseResourceNotExists = (object: any, field_name: string) => { if (!object) { throw { status: 404, error: true, body: { status: 'Not Found', - description: `Resource with the provided ${file_name} does not exists.` + description: `Resource with the provided ${field_name} does not exists.` }, headers: { 'Content-Type': 'application/json'