This commit is contained in:
Benjamin Toby 2024-11-06 07:26:23 +01:00
parent d81f38809b
commit 190598aa3f
42 changed files with 3766 additions and 298 deletions

View File

@ -3,9 +3,9 @@
* No imports found for this Module * No imports found for this Module
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check const runQuery = require("../../package-shared/functions/backend/db/runQuery");
const runQuery = require("./utils/runQuery"); // @ts-check
/** /**
* @typedef {Object} LocalGetReturn * @typedef {Object} LocalGetReturn
@ -39,7 +39,6 @@ async function localGet({ options, dbSchema }) {
/** @type {string | undefined | any } */ /** @type {string | undefined | any } */
const tableName = options?.tableName ? options.tableName : undefined; const tableName = options?.tableName ? options.tableName : undefined;
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
/** /**
@ -71,6 +70,7 @@ async function localGet({ options, dbSchema }) {
queryValuesArray: queryValues, queryValuesArray: queryValues,
dbSchema, dbSchema,
tableName, tableName,
local: true,
}); });
if (error) throw error; if (error) throw error;

View File

@ -1,6 +1,6 @@
// @ts-check // @ts-check
const runQuery = require("./utils/runQuery"); const runQuery = require("../../package-shared/functions/backend/db/runQuery");
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
@ -52,6 +52,7 @@ async function localPost({ options, dbSchema }) {
dbSchema: dbSchema, dbSchema: dbSchema,
queryValuesArray: queryValues, queryValuesArray: queryValues,
tableName, tableName,
local: true,
}); });
if (error) throw error; if (error) throw error;

View File

@ -1,184 +0,0 @@
// @ts-check
/**
* Imports: Handle imports
*/
const encrypt = require("../../../functions/encrypt");
const dbHandler = require("../../engine/utils/dbHandler");
const updateDb = require("./updateDbEntry");
const updateDbEntry = require("./updateDbEntry");
/**
* Add a db Entry Function
* ==============================================================================
* @description Description
* @async
*
* @param {object} params - An object containing the function parameters.
* "Read only" or "Full Access"? Defaults to "Read Only"
* @param {string} params.dbFullName - Database full name
* @param {string} params.tableName - Table name
* @param {*} params.data - Data to add
* @param {import("../../../package-shared/types").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @param {string} [params.duplicateColumnName] - Duplicate column name
* @param {string} [params.duplicateColumnValue] - Duplicate column value
* @param {boolean} [params.update] - Update this row if it exists
* @param {string} params.encryptionKey - Update this row if it exists
* @param {string} params.encryptionSalt - Update this row if it exists
*
* @returns {Promise<*>}
*/
async function addDbEntry({
dbFullName,
tableName,
data,
tableSchema,
duplicateColumnName,
duplicateColumnValue,
update,
encryptionKey,
encryptionSalt,
}) {
/**
* Initialize variables
*/
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Handle function logic
*/
if (duplicateColumnName && typeof duplicateColumnName === "string") {
const duplicateValue = await dbHandler({
database: dbFullName,
query: `SELECT * FROM \`${tableName}\` WHERE \`${duplicateColumnName}\`=?`,
values: [duplicateColumnValue || ""],
});
if (duplicateValue && duplicateValue[0] && !update) {
return null;
} else if (duplicateValue && duplicateValue[0] && update) {
return await updateDbEntry({
dbFullName,
tableName,
data,
tableSchema,
identifierColumnName: duplicateColumnName,
identifierValue: duplicateColumnValue || "",
encryptionKey,
encryptionSalt,
});
}
}
/**
* Declare variables
*
* @description Declare "results" variable
*/
const dataKeys = Object.keys(data);
let insertKeysArray = [];
let insertValuesArray = [];
for (let i = 0; i < dataKeys.length; i++) {
try {
const dataKey = dataKeys[i];
let value = data[dataKey];
const targetFieldSchemaArray = tableSchema
? tableSchema?.fields?.filter(
(field) => field.fieldName == dataKey
)
: null;
const targetFieldSchema =
targetFieldSchemaArray && targetFieldSchemaArray[0]
? targetFieldSchemaArray[0]
: null;
if (!value) continue;
if (targetFieldSchema?.encrypted) {
value = encrypt({ data: value, encryptionKey, encryptionSalt });
console.log("DSQL: Encrypted value =>", value);
}
if (targetFieldSchema?.pattern) {
const pattern = new RegExp(
targetFieldSchema.pattern,
targetFieldSchema.patternFlags || ""
);
if (!value?.toString()?.match(pattern)) {
console.log("DSQL: Pattern not matched =>", value);
value = "";
}
}
if (typeof value === "string" && !value.match(/./i)) {
value = {
toSqlString: function () {
return "NULL";
},
};
}
insertKeysArray.push("`" + dataKey + "`");
if (typeof value === "object") {
value = JSON.stringify(value);
}
insertValuesArray.push(value);
} catch (/** @type {*} */ error) {
console.log("DSQL: Error in parsing data keys =>", error.message);
continue;
}
}
////////////////////////////////////////
insertKeysArray.push("`date_created`");
insertValuesArray.push(Date());
insertKeysArray.push("`date_created_code`");
insertValuesArray.push(Date.now());
////////////////////////////////////////
insertKeysArray.push("`date_updated`");
insertValuesArray.push(Date());
insertKeysArray.push("`date_updated_code`");
insertValuesArray.push(Date.now());
////////////////////////////////////////
const query = `INSERT INTO \`${tableName}\` (${insertKeysArray.join(
","
)}) VALUES (${insertValuesArray.map(() => "?").join(",")})`;
const queryValuesArray = insertValuesArray;
const newInsert = await dbHandler({
database: dbFullName,
query: query,
values: queryValuesArray,
});
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Return statement
*/
return newInsert;
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
module.exports = addDbEntry;

View File

@ -1,10 +1,9 @@
// @ts-check // @ts-check
const hashPassword = require("../../functions/hashPassword"); const hashPassword = require("../../functions/hashPassword");
const addDbEntry = require("../../package-shared/functions/backend/db/addDbEntry");
const addUsersTableToDb = require("../engine/addUsersTableToDb"); const addUsersTableToDb = require("../engine/addUsersTableToDb");
const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler");
const addDbEntry = require("../query/utils/addDbEntry");
const runQuery = require("../query/utils/runQuery");
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API

View File

@ -8,8 +8,8 @@
const fs = require("fs"); const fs = require("fs");
const http = require("http"); const http = require("http");
const varDatabaseDbHandler = require("../../../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../../../engine/utils/varDatabaseDbHandler");
const addDbEntry = require("../../../query/utils/addDbEntry");
const encrypt = require("../../../../functions/encrypt"); const encrypt = require("../../../../functions/encrypt");
const addDbEntry = require("../../../../package-shared/functions/backend/db/addDbEntry");
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////

View File

@ -1,6 +1,6 @@
// @ts-check // @ts-check
const updateDbEntry = require("../query/utils/updateDbEntry"); const updateDbEntry = require("../../package-shared/functions/backend/db/updateDbEntry");
/** /**
* @typedef {Object} LocalPostReturn * @typedef {Object} LocalPostReturn

300
package-lock.json generated
View File

@ -1,32 +1,62 @@
{ {
"name": "datasquirel", "name": "datasquirel",
"version": "2.1.1", "version": "2.3.5",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "datasquirel", "name": "datasquirel",
"version": "2.1.1", "version": "2.3.5",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@types/ace": "^0.0.52",
"@types/react": "^18.3.12",
"@types/tinymce": "^4.6.9",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"generate-password": "^1.7.1",
"lodash": "^4.17.21",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"nodemailer": "^6.9.14" "nodemailer": "^6.9.14",
"sanitize-html": "^2.13.1",
"serverless-mysql": "^1.5.5"
}, },
"bin": { "bin": {
"dsql-dump": "engine/dump.js", "dsql-dump": "engine/dump.js",
"dsql-watch": "engine/dsql.js" "dsql-watch": "engine/dsql.js"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.17.13",
"@types/mysql": "^2.15.21", "@types/mysql": "^2.15.21",
"@types/node": "^22.7.5" "@types/node": "^22.7.5"
} }
}, },
"node_modules/@types/ace": {
"version": "0.0.52",
"resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz",
"integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==",
"license": "MIT"
},
"node_modules/@types/jquery": {
"version": "3.5.32",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
"integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==",
"license": "MIT",
"dependencies": {
"@types/sizzle": "*"
}
},
"node_modules/@types/lodash": {
"version": "4.17.13",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz",
"integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/mysql": { "node_modules/@types/mysql": {
"version": "2.15.21", "version": "2.15.21",
"resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.21.tgz", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.21.tgz",
"integrity": "sha512-NPotx5CVful7yB+qZbWtXL2fA4e7aEHkihHLjklc6ID8aq7bhguHgeIoC1EmSNTAuCgI6ZXrjt2ZSaXnYX0EUg==", "integrity": "sha512-NPotx5CVful7yB+qZbWtXL2fA4e7aEHkihHLjklc6ID8aq7bhguHgeIoC1EmSNTAuCgI6ZXrjt2ZSaXnYX0EUg==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"@types/node": "*" "@types/node": "*"
} }
@ -35,12 +65,43 @@
"version": "22.7.5", "version": "22.7.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
} }
}, },
"node_modules/@types/prop-types": {
"version": "15.7.13",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
"integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.3.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz",
"integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==",
"license": "MIT",
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/sizzle": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz",
"integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==",
"license": "MIT"
},
"node_modules/@types/tinymce": {
"version": "4.6.9",
"resolved": "https://registry.npmjs.org/@types/tinymce/-/tinymce-4.6.9.tgz",
"integrity": "sha512-pDxBUlV4v1jgJ97SlnVOSyf3KUy3OQ3s5Ddpfh1L9M5lXlBmX7TJ2OLSozx1WBxp91acHvYPWDwz2U/kMM1oxQ==",
"license": "MIT",
"dependencies": {
"@types/jquery": "*"
}
},
"node_modules/bignumber.js": { "node_modules/bignumber.js": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
@ -54,6 +115,76 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
}, },
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"license": "BSD-2-Clause"
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.3.1", "version": "16.3.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
@ -65,16 +196,80 @@
"url": "https://github.com/motdotla/dotenv?sponsor=1" "url": "https://github.com/motdotla/dotenv?sponsor=1"
} }
}, },
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/generate-password": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.1.tgz",
"integrity": "sha512-9bVYY+16m7W7GczRBDqXE+VVuCX+bWNrfYKC/2p2JkZukFb2sKxT6E3zZ3mJGz7GMe5iRK0A/WawSL3jQfJuNQ==",
"license": "MIT"
},
"node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
}, },
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/isarray": { "node_modules/isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
}, },
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/mysql": { "node_modules/mysql": {
"version": "2.18.1", "version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
@ -89,6 +284,24 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/nodemailer": { "node_modules/nodemailer": {
"version": "6.9.14", "version": "6.9.14",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz",
@ -98,6 +311,46 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/parse-srcset": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC"
},
"node_modules/postcss": {
"version": "8.4.47",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.0",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/process-nextick-args": { "node_modules/process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -122,6 +375,41 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}, },
"node_modules/sanitize-html": {
"version": "2.13.1",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.13.1.tgz",
"integrity": "sha512-ZXtKq89oue4RP7abL9wp/9URJcqQNABB5GGJ2acW1sdO8JTVl92f4ygD7Yc9Ze09VAZhnt2zegeU0tbNsdcLYg==",
"license": "MIT",
"dependencies": {
"deepmerge": "^4.2.2",
"escape-string-regexp": "^4.0.0",
"htmlparser2": "^8.0.0",
"is-plain-object": "^5.0.0",
"parse-srcset": "^1.0.2",
"postcss": "^8.3.11"
}
},
"node_modules/serverless-mysql": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/serverless-mysql/-/serverless-mysql-1.5.5.tgz",
"integrity": "sha512-QwaCtswn3GKCnqyVA0whwDFMIw91iKTeTvf6F++HoGiunfyvfJ2MdU8d3MKMQdKGNOXIvmUlLq/JVjxuPQxkrw==",
"license": "MIT",
"dependencies": {
"mysql": "^2.18.1"
},
"optionalDependencies": {
"@types/mysql": "^2.15.6"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sqlstring": { "node_modules/sqlstring": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
@ -142,7 +430,7 @@
"version": "6.19.8", "version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/util-deprecate": { "node_modules/util-deprecate": {

View File

@ -1,3 +1,7 @@
# Shared resources # Shared resources
This directory contains data (mostly type definitions) shared by both the datasquirel NPM package and the datasquirel web app This directory contains data (mostly type definitions) shared by both the datasquirel NPM package and the datasquirel web app
## Functions
## Types

View File

@ -0,0 +1,66 @@
// @ts-check
const generator = require("generate-password");
const DB_HANDLER = require("../../utils/backend/global-db/DB_HANDLER");
const NO_DB_HANDLER = require("../../utils/backend/global-db/NO_DB_HANDLER");
const encrypt = require("./encrypt");
const addDbEntry = require("./db/addDbEntry");
/**
* # Add Mariadb User
*
* @description this function adds a Mariadb user to the database server
*
* @param {object} params - parameters object *
* @param {number | string} params.userId - invited user object
*
* @returns {Promise<any>} new user auth object payload
*/
module.exports = async function addMariadbUser({ userId }) {
try {
const defaultMariadbUserHost = process.env.DSQL_DB_HOST || "127.0.0.1";
const username = `dsql_user_${userId}`;
const password = generator.generate({
length: 16,
numbers: true,
symbols: true,
uppercase: true,
exclude: "*#.'`\"",
});
const encryptedPassword = encrypt(password);
await NO_DB_HANDLER(
`CREATE USER IF NOT EXISTS '${username}'@'127.0.0.1' IDENTIFIED BY '${password}' REQUIRE SSL`
);
const updateUser = await DB_HANDLER(
`UPDATE users SET mariadb_user = ?, mariadb_host = '127.0.0.1', mariadb_pass = ? WHERE id = ?`,
[username, encryptedPassword, userId]
);
const addMariadbUser = await addDbEntry({
tableName: "mariadb_users",
data: {
user_id: userId,
username,
host: defaultMariadbUserHost,
password: encryptedPassword,
primary: "1",
grants: '[{"database":"*","table":"*","privileges":["ALL"]}]',
},
dbContext: "Master",
});
console.log(`User ${userId} SQL credentials successfully added.`);
} catch (/** @type {any} */ error) {
console.log(
`Error in adding SQL user in 'addMariadbUser' function =>`,
error.message
);
}
};
////////////////////////////////////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////

View File

@ -0,0 +1,43 @@
// @ts-check
const fs = require("fs");
const decrypt = require("./decrypt");
/** @type {import("../../types").CheckApiCredentialsFn} */
const grabApiCred = ({ key, database, table }) => {
try {
const allowedKeysPath = process.env.DSQL_API_KEYS_PATH;
if (!allowedKeysPath)
throw new Error(
"process.env.DSQL_API_KEYS_PATH variable not found"
);
const ApiJSON = decrypt(key);
/** @type {import("../../types").ApiKeyObject} */
const ApiObject = JSON.parse(ApiJSON || "");
const isApiKeyValid = fs.existsSync(
`${allowedKeysPath}/${ApiObject.sign}`
);
if (!isApiKeyValid) return null;
if (!ApiObject.target_database) return ApiObject;
if (!database && ApiObject.target_database) return null;
const isDatabaseAllowed = ApiObject.target_database
?.split(",")
.includes(String(database));
if (isDatabaseAllowed && !ApiObject.target_table) return ApiObject;
if (isDatabaseAllowed && !table && ApiObject.target_table) return null;
const isTableAllowed = ApiObject.target_table
?.split(",")
.includes(String(table));
if (isTableAllowed) return ApiObject;
return null;
} catch (/** @type {any} */ error) {
console.log(`api-cred ERROR: ${error.message}`);
return null;
}
};
module.exports = grabApiCred;

View File

@ -0,0 +1,163 @@
// @ts-check
const fs = require("fs");
const DB_HANDLER = require("../../../utils/backend/global-db/DB_HANDLER");
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* Add Database Entry
* ==============================================================================
* @param {object} params - foundUser if any
* @param {string} params.tableName - Table Name
* @param {any} params.data - Data to be added
* @param {string} [params.duplicateColumnName] - Duplicate Column Name
* @param {string | number} [params.duplicateColumnValue] - Duplicate Column Value
*/
module.exports = async function addDbEntry({
tableName,
data,
duplicateColumnName,
duplicateColumnValue,
}) {
/**
* Check Duplicate if specified
*
* @description Check Duplicate if specified
*/
if (duplicateColumnName) {
let duplicateEntry = await DB_HANDLER(
`SELECT ${duplicateColumnName} FROM ${tableName} WHERE ${duplicateColumnName}='${duplicateColumnValue}'`
);
if (duplicateEntry && duplicateEntry[0]) return null;
}
/**
* Declare variables
*
* @description Declare "results" variable
*/
const dataKeys = Object.keys(data);
let insertKeysArray = [];
let insertValuesArray = [];
for (let i = 0; i < dataKeys.length; i++) {
const dataKey = dataKeys[i];
let dataValue = data[dataKey];
// const correspondingColumnObject = dbColumns.filter((col) => col.Field === dataKey);
// const { Field, Type, Null, Key, Default, Extra } = correspondingColumnObject;
if (!dataValue) continue;
insertKeysArray.push("`" + dataKey + "`");
if (typeof dataValue === "object") {
dataValue = JSON.stringify(data[dataKey]);
}
// let parsedDataValue = dataValue.toString().replace(/\'/g, "\\'");
insertValuesArray.push(dataValue);
}
////////////////////////////////////////
// @ts-ignore
let existingDateCreatedColumn = await DB_HANDLER(
`SHOW COLUMNS FROM \`${tableName}\` WHERE Field = 'date_created'`
);
if (!existingDateCreatedColumn || !existingDateCreatedColumn[0]) {
// @ts-ignore
await DB_HANDLER(
`ALTER TABLE ${tableName} ADD COLUMN date_created VARCHAR(255) NOT NULL`
);
}
insertKeysArray.push("date_created");
insertValuesArray.push(Date());
////////////////////////////////////////
// @ts-ignore
let existingDateCreatedCodeColumn = await DB_HANDLER(
`SHOW COLUMNS FROM ${tableName} WHERE Field = 'date_created_code'`
);
if (!existingDateCreatedCodeColumn || !existingDateCreatedCodeColumn[0]) {
// @ts-ignore
await DB_HANDLER(
`ALTER TABLE ${tableName} ADD COLUMN date_created_code BIGINT NOT NULL`
);
}
insertKeysArray.push("date_created_code");
insertValuesArray.push(Date.now());
////////////////////////////////////////
// @ts-ignore
let existingDateCodeColumn = await DB_HANDLER(
`SHOW COLUMNS FROM ${tableName} WHERE Field = 'date_code'`
);
if (existingDateCodeColumn && existingDateCodeColumn[0]) {
insertKeysArray.push("date_code");
insertValuesArray.push(Date.now());
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
// @ts-ignore
let existingDateUpdatedColumn = await DB_HANDLER(
`SHOW COLUMNS FROM ${tableName} WHERE Field = 'date_updated'`
);
if (!existingDateUpdatedColumn || !existingDateUpdatedColumn[0]) {
// @ts-ignore
await DB_HANDLER(
`ALTER TABLE ${tableName} ADD COLUMN date_updated VARCHAR(255) NOT NULL`
);
}
insertKeysArray.push("date_updated");
insertValuesArray.push(Date());
////////////////////////////////////////
// @ts-ignore
let existingDateUpdatedCodeColumn = await DB_HANDLER(
`SHOW COLUMNS FROM ${tableName} WHERE Field = 'date_updated_code'`
);
if (!existingDateUpdatedCodeColumn || !existingDateUpdatedCodeColumn[0]) {
// @ts-ignore
await DB_HANDLER(
`ALTER TABLE ${tableName} ADD COLUMN date_updated_code BIGINT NOT NULL`
);
}
insertKeysArray.push("date_updated_code");
insertValuesArray.push(Date.now());
////////////////////////////////////////
const query = `INSERT INTO ${tableName} (${insertKeysArray.join(
","
)}) VALUES (${insertValuesArray.map((val) => "?").join(",")})`;
const queryValuesArray = insertValuesArray;
// @ts-ignore
const newInsert = await DB_HANDLER(query, queryValuesArray);
////////////////////////////////////////
return newInsert;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
};

View File

@ -0,0 +1,232 @@
// @ts-check
/**
* Imports: Handle imports
*/
const encrypt = require("../encrypt");
const sanitizeHtml = require("sanitize-html");
const sanitizeHtmlOptions = require("../html/sanitizeHtmlOptions");
const updateDb = require("./updateDbEntry");
const updateDbEntry = require("./updateDbEntry");
const _ = require("lodash");
const DB_HANDLER = require("../../../utils/backend/global-db/DB_HANDLER");
const DSQL_USER_DB_HANDLER = require("../../../utils/backend/global-db/DSQL_USER_DB_HANDLER");
/**
* Add a db Entry Function
* ==============================================================================
* @description Description
* @async
*
* @param {object} params - An object containing the function parameters.
* @param {("Master" | "Dsql User")} [params.dbContext] - What is the database context? "Master"
* or "Dsql User". Defaults to "Master"
* @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"?
* "Read only" or "Full Access"? Defaults to "Read Only"
* @param {string} [params.dbFullName] - Database full name
* @param {string} params.tableName - Table name
* @param {any} params.data - Data to add
* @param {import("../../../types").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @param {string} [params.duplicateColumnName] - Duplicate column name
* @param {string} [params.duplicateColumnValue] - Duplicate column value
* @param {boolean} [params.update] - Update this row if it exists
* @param {string} [params.encryptionKey] - Update this row if it exists
* @param {string} [params.encryptionSalt] - Update this row if it exists
*
* @returns {Promise<any>}
*/
async function addDbEntry({
dbContext,
paradigm,
dbFullName,
tableName,
data,
tableSchema,
duplicateColumnName,
duplicateColumnValue,
update,
encryptionKey,
encryptionSalt,
}) {
/**
* Initialize variables
*/
const isMaster = dbContext?.match(/dsql.user/i)
? false
: dbFullName && !dbFullName.match(/^datasquirel$/)
? false
: true;
/** @type { any } */
const dbHandler = isMaster ? DB_HANDLER : DSQL_USER_DB_HANDLER;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
if (data?.["date_created_timestamp"]) delete data["date_created_timestamp"];
if (data?.["date_updated_timestamp"]) delete data["date_updated_timestamp"];
if (data?.["date_updated"]) delete data["date_updated"];
if (data?.["date_updated_code"]) delete data["date_updated_code"];
if (data?.["date_created"]) delete data["date_created"];
if (data?.["date_created_code"]) delete data["date_created_code"];
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Handle function logic
*/
if (duplicateColumnName && typeof duplicateColumnName === "string") {
const duplicateValue = isMaster
? await dbHandler(
`SELECT * FROM \`${tableName}\` WHERE \`${duplicateColumnName}\`=?`,
[duplicateColumnValue]
)
: await dbHandler({
paradigm: "Read Only",
database: dbFullName,
queryString: `SELECT * FROM \`${tableName}\` WHERE \`${duplicateColumnName}\`=?`,
queryValues: [duplicateColumnValue],
});
if (duplicateValue?.[0] && !update) {
return null;
} else if (duplicateValue && duplicateValue[0] && update) {
return await updateDbEntry({
dbContext,
paradigm,
dbFullName,
tableName,
data,
tableSchema,
encryptionKey,
encryptionSalt,
identifierColumnName: duplicateColumnName,
identifierValue: duplicateColumnValue || "",
});
}
}
/**
* Declare variables
*
* @description Declare "results" variable
*/
const dataKeys = Object.keys(data);
let insertKeysArray = [];
let insertValuesArray = [];
for (let i = 0; i < dataKeys.length; i++) {
try {
const dataKey = dataKeys[i];
// @ts-ignore
let value = data?.[dataKey];
const targetFieldSchemaArray = tableSchema
? tableSchema?.fields?.filter(
(field) => field.fieldName == dataKey
)
: null;
const targetFieldSchema =
targetFieldSchemaArray && targetFieldSchemaArray[0]
? targetFieldSchemaArray[0]
: null;
if (value == null || value == undefined) continue;
if (targetFieldSchema?.encrypted) {
value = encrypt(value, encryptionKey, encryptionSalt);
console.log("DSQL: Encrypted value =>", value);
}
if (targetFieldSchema?.richText) {
value = sanitizeHtml(value, sanitizeHtmlOptions);
}
if (targetFieldSchema?.pattern) {
const pattern = new RegExp(
targetFieldSchema.pattern,
targetFieldSchema.patternFlags || ""
);
if (!pattern.test(value)) {
console.log("DSQL: Pattern not matched =>", value);
value = "";
}
}
insertKeysArray.push("`" + dataKey + "`");
if (typeof value === "object") {
value = JSON.stringify(value);
}
if (typeof value == "number") {
insertValuesArray.push(String(value));
} else {
insertValuesArray.push(value);
}
} catch (/** @type {any} */ error) {
console.log("DSQL: Error in parsing data keys =>", error.message);
continue;
}
}
////////////////////////////////////////
if (!data?.["date_created"]) {
insertKeysArray.push("`date_created`");
insertValuesArray.push(Date());
}
if (!data?.["date_created_code"]) {
insertKeysArray.push("`date_created_code`");
insertValuesArray.push(Date.now());
}
////////////////////////////////////////
if (!data?.["date_updated"]) {
insertKeysArray.push("`date_updated`");
insertValuesArray.push(Date());
}
if (!data?.["date_updated_code"]) {
insertKeysArray.push("`date_updated_code`");
insertValuesArray.push(Date.now());
}
////////////////////////////////////////
const query = `INSERT INTO \`${tableName}\` (${insertKeysArray.join(
","
)}) VALUES (${insertValuesArray.map(() => "?").join(",")})`;
const queryValuesArray = insertValuesArray;
const newInsert = isMaster
? await dbHandler(query, queryValuesArray)
: await dbHandler({
paradigm,
database: dbFullName,
queryString: query,
queryValues: queryValuesArray,
});
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Return statement
*/
return newInsert;
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
module.exports = addDbEntry;

View File

@ -1,6 +1,7 @@
// @ts-check // @ts-check
const dbHandler = require("../../engine/utils/dbHandler"); const DB_HANDLER = require("../../../utils/backend/global-db/DB_HANDLER");
const DSQL_USER_DB_HANDLER = require("../../../utils/backend/global-db/DSQL_USER_DB_HANDLER");
/** /**
* Imports: Handle imports * Imports: Handle imports
@ -19,7 +20,7 @@ const dbHandler = require("../../engine/utils/dbHandler");
* "Read only" or "Full Access"? Defaults to "Read Only" * "Read only" or "Full Access"? Defaults to "Read Only"
* @param {string} params.dbFullName - Database full name * @param {string} params.dbFullName - Database full name
* @param {string} params.tableName - Table name * @param {string} params.tableName - Table name
* @param {import("../../../package-shared/types").DSQL_TableSchemaType} [params.tableSchema] - Table schema * @param {import("../../../types").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @param {string} params.identifierColumnName - Update row identifier column name * @param {string} params.identifierColumnName - Update row identifier column name
* @param {string|number} params.identifierValue - Update row identifier column value * @param {string|number} params.identifierValue - Update row identifier column value
* *
@ -37,6 +38,14 @@ async function deleteDbEntry({
/** /**
* Check if data is valid * Check if data is valid
*/ */
const isMaster = dbContext?.match(/dsql.user/i)
? false
: dbFullName && !dbFullName.match(/^datasquirel$/)
? false
: true;
/** @type { (a1:any, a2?:any) => any } */
const dbHandler = isMaster ? DB_HANDLER : DSQL_USER_DB_HANDLER;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
@ -49,11 +58,14 @@ async function deleteDbEntry({
*/ */
const query = `DELETE FROM ${tableName} WHERE \`${identifierColumnName}\`=?`; const query = `DELETE FROM ${tableName} WHERE \`${identifierColumnName}\`=?`;
const deletedEntry = await dbHandler({ const deletedEntry = isMaster
query: query, ? await dbHandler(query, [identifierValue])
database: dbFullName, : await dbHandler({
values: [identifierValue], paradigm,
}); queryString: query,
database: dbFullName,
queryValues: [identifierValue],
});
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -0,0 +1,41 @@
// @ts-check
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Sanitize SQL function
* ==============================================================================
* @description this function takes in a text(or number) and returns a sanitized
* text, usually without spaces
*
* @param {string|number} text - Text or number or object
*
* @returns {string}
*/
function pathTraversalCheck(text) {
/**
* Initial Checks
*
* @description Initial Checks
*/
return text.toString().replace(/\//g, "");
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
module.exports = pathTraversalCheck;

View File

@ -1,21 +1,25 @@
/** # MODULE TRACE /** # MODULE TRACE
====================================================================== ======================================================================
* Detected 4 files that call this module. The files are listed below: * Detected 3 files that call this module. The files are listed below:
====================================================================== ======================================================================
* `require` Statement Found in [get.js](d:\GitHub\dsql\engine\query\get.js) * `import` Statement Found in [get.js] => file:///d:\GitHub\datasquirel\pages\api\query\get.js
* `require` Statement Found in [post.js](d:\GitHub\dsql\engine\query\post.js) * `import` Statement Found in [post.js] => file:///d:\GitHub\datasquirel\pages\api\query\post.js
* `require` Statement Found in [add-user.js](d:\GitHub\dsql\engine\user\add-user.js) * `import` Statement Found in [add-user.js] => file:///d:\GitHub\datasquirel\pages\api\user\add-user.js
* `require` Statement Found in [update-user.js](d:\GitHub\dsql\engine\user\update-user.js)
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check // @ts-check
const fs = require("fs"); const fs = require("fs");
const fullAccessDbHandler = require("../fullAccessDbHandler");
const varReadOnlyDatabaseDbHandler = require("../varReadOnlyDatabaseDbHandler");
const serverError = require("../serverError");
const addDbEntry = require("./addDbEntry"); const addDbEntry = require("./addDbEntry");
const updateDbEntry = require("./updateDbEntry"); const updateDbEntry = require("./updateDbEntry");
const deleteDbEntry = require("./deleteDbEntry"); const deleteDbEntry = require("./deleteDbEntry");
const varDatabaseDbHandler = require("../../engine/utils/varDatabaseDbHandler"); const DB_HANDLER = require("../../../utils/backend/global-db/DB_HANDLER");
const parseDbResults = require("../parseDbResults");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
@ -29,13 +33,14 @@ const varDatabaseDbHandler = require("../../engine/utils/varDatabaseDbHandler");
* ============================================================================== * ==============================================================================
* @param {object} params - An object containing the function parameters. * @param {object} params - An object containing the function parameters.
* @param {string} params.dbFullName - Database full name. Eg. "datasquire_user_2_test" * @param {string} params.dbFullName - Database full name. Eg. "datasquire_user_2_test"
* @param {*} params.query - Query string or object * @param {string | any} params.query - Query string or object
* @param {boolean} [params.readOnly] - Is this operation read only? * @param {boolean} [params.readOnly] - Is this operation read only?
* @param {import("../../../package-shared/types").DSQL_DatabaseSchemaType} [params.dbSchema] - Database schema * @param {boolean} [params.local] - Is this operation read only?
* @param {import("../../../types").DSQL_DatabaseSchemaType} [params.dbSchema] - Database schema
* @param {string[]} [params.queryValuesArray] - An optional array of query values if "?" is used in the query string * @param {string[]} [params.queryValuesArray] - An optional array of query values if "?" is used in the query string
* @param {string} [params.tableName] - Table Name * @param {string} [params.tableName] - Table Name
* *
* @return {Promise<{result: *, error?: *}>} * @return {Promise<any>}
*/ */
async function runQuery({ async function runQuery({
dbFullName, dbFullName,
@ -44,16 +49,20 @@ async function runQuery({
dbSchema, dbSchema,
queryValuesArray, queryValuesArray,
tableName, tableName,
local,
}) { }) {
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
let result, error, tableSchema; /** @type {any} */
let result;
/** @type {any} */
let error;
/** @type {import("../../../types").DSQL_TableSchemaType | undefined} */
let tableSchema;
if (dbSchema) { if (dbSchema) {
try { try {
@ -68,7 +77,9 @@ async function runQuery({
tableSchema = dbSchema.tables.filter( tableSchema = dbSchema.tables.filter(
(tb) => tb?.tableName === table (tb) => tb?.tableName === table
)[0]; )[0];
} catch (_err) {} } catch (_err) {
// console.log("ERROR getting tableSchema: ", _err.message);
}
} }
/** /**
@ -78,12 +89,29 @@ async function runQuery({
*/ */
try { try {
if (typeof query === "string") { if (typeof query === "string") {
result = await varDatabaseDbHandler({ if (local) {
queryString: query, const rawResults = await DB_HANDLER(query, queryValuesArray);
queryValuesArray, result = tableSchema
database: dbFullName, ? parseDbResults({
tableSchema, unparsedResults: rawResults,
}); tableSchema,
})
: rawResults;
} else if (readOnly) {
result = await varReadOnlyDatabaseDbHandler({
queryString: query,
queryValuesArray,
database: dbFullName,
tableSchema,
});
} else {
result = await fullAccessDbHandler({
queryString: query,
queryValuesArray,
database: dbFullName,
tableSchema,
});
}
} else if (typeof query === "object") { } else if (typeof query === "object") {
/** /**
* Declare variables * Declare variables
@ -104,6 +132,8 @@ async function runQuery({
switch (action.toLowerCase()) { switch (action.toLowerCase()) {
case "insert": case "insert":
result = await addDbEntry({ result = await addDbEntry({
dbContext: local ? "Master" : "Dsql User",
paradigm: "Full Access",
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: table, tableName: table,
data: data, data: data,
@ -111,8 +141,6 @@ async function runQuery({
duplicateColumnName, duplicateColumnName,
duplicateColumnValue, duplicateColumnValue,
tableSchema, tableSchema,
encryptionKey,
encryptionSalt,
}); });
if (!result?.insertId) { if (!result?.insertId) {
@ -123,7 +151,7 @@ async function runQuery({
case "update": case "update":
result = await updateDbEntry({ result = await updateDbEntry({
dbContext: "Dsql User", dbContext: local ? "Master" : "Dsql User",
paradigm: "Full Access", paradigm: "Full Access",
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: table, tableName: table,
@ -131,15 +159,13 @@ async function runQuery({
identifierColumnName, identifierColumnName,
identifierValue, identifierValue,
tableSchema, tableSchema,
encryptionKey,
encryptionSalt,
}); });
break; break;
case "delete": case "delete":
result = await deleteDbEntry({ result = await deleteDbEntry({
dbContext: "Dsql User", dbContext: local ? "Master" : "Dsql User",
paradigm: "Full Access", paradigm: "Full Access",
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: table, tableName: table,
@ -151,12 +177,7 @@ async function runQuery({
break; break;
default: default:
console.log("Unhandled Query"); result = null;
console.log("Query Recieved =>", query);
result = {
result: null,
error: "Unhandled Query",
};
break; break;
} }
} }
@ -164,14 +185,12 @@ async function runQuery({
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {any} */ error) {
console.log("Error in Running Query =>", error.message); serverError({
console.log("Query Recieved =>", query); component: "functions/backend/runQuery",
message: error.message,
result = { });
result: null, result = null;
error: "Error in running Query => " + error.message,
};
error = error.message; error = error.message;
} }

View File

@ -0,0 +1,207 @@
// @ts-check
const _ = require("lodash");
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Sanitize SQL function
* ==============================================================================
* @description this function takes in a text(or number) and returns a sanitized
* text, usually without spaces
*
* @param {any} text - Text or number or object
* @param {boolean} [spaces] - Allow spaces
* @param {RegExp?} [regex] - Regular expression, removes any match
*
* @returns {any}
*/
function sanitizeSql(text, spaces, regex) {
/**
* Initial Checks
*
* @description Initial Checks
*/
if (!text) return "";
if (typeof text == "number" || typeof text == "boolean") return text;
if (typeof text == "string" && !text?.toString()?.match(/./)) return "";
if (typeof text == "object" && !Array.isArray(text)) {
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
const newObject = sanitizeObjects(text, spaces);
return newObject;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
} else if (typeof text == "object" && Array.isArray(text)) {
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
const newArray = sanitizeArrays(text, spaces);
return newArray;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
}
// if (text?.toString()?.match(/\'|\"/)) {
// console.log("TEXT containing commas =>", text);
// return "";
// }
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Declare variables
*
* @description Declare "results" variable
*/
let finalText = text;
if (regex) {
finalText = text.toString().replace(regex, "");
}
if (spaces) {
} else {
finalText = text
.toString()
.replace(/\n|\r|\n\r|\r\n/g, "")
.replace(/ /g, "");
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
const escapeRegex =
/select |insert |drop |delete |alter |create |exec | union | or | like | concat|LOAD_FILE|ASCII| COLLATE | HAVING | information_schema|DECLARE |\#|WAITFOR |delay |BENCHMARK |\/\*.*\*\//gi;
finalText = finalText
.replace(/(?<!\\)\'/g, "\\'")
.replace(/(?<!\\)\`/g, "\\`")
// .replace(/(?<!\\)\"/g, '\\"')
.replace(/\/\*\*\//g, "")
.replace(escapeRegex, "\\$&");
// const injectionRegexp = /select .* from|\*|delete from|drop database|drop table|update .* set/i;
// if (text?.toString()?.match(injectionRegexp)) {
// console.log("ATTEMPTED INJECTION =>", text);
// return "";
// }
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
return finalText;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Sanitize Objects Function
* ==============================================================================
* @description Sanitize objects in the form { key: "value" }
*
* @param {any} object - Database Full Name
* @param {boolean} [spaces] - Allow spaces
*
* @returns {object}
*/
function sanitizeObjects(object, spaces) {
/** @type {any} */
let objectUpdated = { ...object };
const keys = Object.keys(objectUpdated);
keys.forEach((key) => {
const value = objectUpdated[key];
if (!value) {
delete objectUpdated[key];
return;
}
if (typeof value == "string" || typeof value == "number") {
objectUpdated[key] = sanitizeSql(value, spaces);
} else if (typeof value == "object" && !Array.isArray(value)) {
objectUpdated[key] = sanitizeObjects(value, spaces);
} else if (typeof value == "object" && Array.isArray(value)) {
objectUpdated[key] = sanitizeArrays(value, spaces);
}
});
return objectUpdated;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Sanitize Objects Function
* ==============================================================================
* @description Sanitize objects in the form { key: "value" }
*
* @param {any[]} array - Database Full Name
* @param {boolean} [spaces] - Allow spaces
*
* @returns {string[]|number[]|object[]}
*/
function sanitizeArrays(array, spaces) {
let arrayUpdated = _.cloneDeep(array);
arrayUpdated.forEach((item, index) => {
const value = item;
if (!value) {
arrayUpdated.splice(index, 1);
return;
}
if (typeof item == "string" || typeof item == "number") {
arrayUpdated[index] = sanitizeSql(value, spaces);
} else if (typeof item == "object" && !Array.isArray(value)) {
arrayUpdated[index] = sanitizeObjects(value, spaces);
} else if (typeof item == "object" && Array.isArray(value)) {
arrayUpdated[index] = sanitizeArrays(item, spaces);
}
});
return arrayUpdated;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
module.exports = sanitizeSql;

View File

@ -1,11 +1,13 @@
// @ts-check // @ts-check
const encrypt = require("../../../functions/encrypt");
const dbHandler = require("../../engine/utils/dbHandler");
/** /**
* Imports: Handle imports * Imports: Handle imports
*/ */
const encrypt = require("../encrypt");
const sanitizeHtml = require("sanitize-html");
const sanitizeHtmlOptions = require("../html/sanitizeHtmlOptions");
const DB_HANDLER = require("../../../utils/backend/global-db/DB_HANDLER");
const DSQL_USER_DB_HANDLER = require("../../../utils/backend/global-db/DSQL_USER_DB_HANDLER");
/** /**
* Update DB Function * Update DB Function
@ -18,14 +20,14 @@ const dbHandler = require("../../engine/utils/dbHandler");
* or "Dsql User". Defaults to "Master" * or "Dsql User". Defaults to "Master"
* @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"? * @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"?
* "Read only" or "Full Access"? Defaults to "Read Only" * "Read only" or "Full Access"? Defaults to "Read Only"
* @param {string} params.dbFullName - Database full name * @param {string} [params.dbFullName] - Database full name
* @param {string} params.tableName - Table name * @param {string} params.tableName - Table name
* @param {*} params.data - Data to add * @param {string} [params.encryptionKey]
* @param {import("../../../package-shared/types").DSQL_TableSchemaType} [params.tableSchema] - Table schema * @param {string} [params.encryptionSalt]
* @param {any} params.data - Data to add
* @param {import("../../../types").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @param {string} params.identifierColumnName - Update row identifier column name * @param {string} params.identifierColumnName - Update row identifier column name
* @param {string | number} params.identifierValue - Update row identifier column value * @param {string | number} params.identifierValue - Update row identifier column value
* @param {string} params.encryptionKey - Encryption key
* @param {string} params.encryptionSalt - Encryption salt
* *
* @returns {Promise<object|null>} * @returns {Promise<object|null>}
*/ */
@ -46,6 +48,15 @@ async function updateDbEntry({
*/ */
if (!data || !Object.keys(data).length) return null; if (!data || !Object.keys(data).length) return null;
const isMaster = dbContext?.match(/dsql.user/i)
? false
: dbFullName && !dbFullName.match(/^datasquirel$/)
? false
: true;
/** @type {(a1:any, a2?:any)=> any } */
const dbHandler = isMaster ? DB_HANDLER : DSQL_USER_DB_HANDLER;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
@ -60,14 +71,10 @@ async function updateDbEntry({
let updateKeyValueArray = []; let updateKeyValueArray = [];
let updateValues = []; let updateValues = [];
/**
* Declare variables
*
* @description Declare "results" variable
*/
for (let i = 0; i < dataKeys.length; i++) { for (let i = 0; i < dataKeys.length; i++) {
try { try {
const dataKey = dataKeys[i]; const dataKey = dataKeys[i];
// @ts-ignore
let value = data[dataKey]; let value = data[dataKey];
const targetFieldSchemaArray = tableSchema const targetFieldSchemaArray = tableSchema
@ -80,22 +87,31 @@ async function updateDbEntry({
? targetFieldSchemaArray[0] ? targetFieldSchemaArray[0]
: null; : null;
if (typeof value == "undefined") continue; if (value == null || value == undefined) continue;
if (
typeof value !== "string" && if (targetFieldSchema?.richText) {
typeof value !== "number" && value = sanitizeHtml(value, sanitizeHtmlOptions);
!value }
)
continue;
if (targetFieldSchema?.encrypted) { if (targetFieldSchema?.encrypted) {
value = encrypt({ data: value, encryptionKey, encryptionSalt }); value = encrypt(value, encryptionKey, encryptionSalt);
} }
if (typeof value === "object") { if (typeof value === "object") {
value = JSON.stringify(value); value = JSON.stringify(value);
} }
if (targetFieldSchema?.pattern) {
const pattern = new RegExp(
targetFieldSchema.pattern,
targetFieldSchema.patternFlags || ""
);
if (!pattern.test(value)) {
console.log("DSQL: Pattern not matched =>", value);
value = "";
}
}
if (typeof value === "string" && value.match(/^null$/i)) { if (typeof value === "string" && value.match(/^null$/i)) {
value = { value = {
toSqlString: function () { toSqlString: function () {
@ -104,17 +120,6 @@ async function updateDbEntry({
}; };
} }
if (targetFieldSchema?.pattern) {
const pattern = new RegExp(
targetFieldSchema.pattern,
targetFieldSchema.patternFlags || ""
);
if (!value?.toString()?.match(pattern)) {
console.log("DSQL: Pattern not matched =>", value);
value = "";
}
}
if (typeof value === "string" && !value.match(/./i)) { if (typeof value === "string" && !value.match(/./i)) {
value = { value = {
toSqlString: function () { toSqlString: function () {
@ -123,14 +128,17 @@ async function updateDbEntry({
}; };
} }
if (!value && typeof value == "number" && value != 0) continue;
updateKeyValueArray.push(`\`${dataKey}\`=?`); updateKeyValueArray.push(`\`${dataKey}\`=?`);
updateValues.push(value);
if (typeof value == "number") {
updateValues.push(String(value));
} else {
updateValues.push(value);
}
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {any} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
@ -157,11 +165,14 @@ async function updateDbEntry({
updateValues.push(identifierValue); updateValues.push(identifierValue);
const updatedEntry = await dbHandler({ const updatedEntry = isMaster
database: dbFullName, ? await dbHandler(query, updateValues)
query: query, : await dbHandler({
values: updateValues, paradigm,
}); database: dbFullName,
queryString: query,
queryValues: updateValues,
});
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -0,0 +1,90 @@
// @ts-check
const fs = require("fs");
const serverError = require("./serverError");
const mysql = require("serverless-mysql");
const path = require("path");
const SSL_DIR = "/app/ssl";
const connection = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_USERNAME,
password: process.env.DSQL_DB_PASSWORD,
database: process.env.DSQL_DB_NAME,
charset: "utf8mb4",
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
/**
* Main DB Handler Function
* ==============================================================================
* @async
*
* @param {any} args
* @returns {Promise<object|null>}
*/
module.exports = async function dbHandler(...args) {
process.env.NODE_ENV?.match(/dev/) &&
fs.appendFileSync(
"./.tmp/sqlQuery.sql",
args[0] + "\n" + Date() + "\n\n\n",
"utf8"
);
/**
* Declare variables
*
* @description Declare "results" variable
*/
let results;
/**
* Fetch from db
*
* @description Fetch data from db if no cache
*/
try {
results = await new Promise((resolve, reject) => {
// @ts-ignore
connection.query(...args, (error, result, fields) => {
if (error) {
resolve({ error: error.message });
} else {
resolve(result);
}
});
});
await connection.end();
} catch (/** @type {any} */ error) {
fs.appendFileSync(
"./.tmp/dbErrorLogs.txt",
JSON.stringify(error, null, 4) + "\n" + Date() + "\n\n\n",
"utf8"
);
results = null;
serverError({
component: "dbHandler",
message: error.message,
});
}
/**
* Return results
*
* @description Return results add to cache if "req" param is passed
*/
if (results) {
return JSON.parse(JSON.stringify(results));
} else {
return null;
}
};

View File

@ -0,0 +1,29 @@
// @ts-check
const { scryptSync, createDecipheriv } = require("crypto");
const { Buffer } = require("buffer");
/**
* @param {string} encryptedString
* @returns {string | null}
*/
const decrypt = (encryptedString) => {
const algorithm = "aes-192-cbc";
const password = process.env.DSQL_ENCRYPTION_PASSWORD || "";
const salt = process.env.DSQL_ENCRYPTION_SALT || "";
let key = scryptSync(password, salt, 24);
let iv = Buffer.alloc(16, 0);
// @ts-ignore
const decipher = createDecipheriv(algorithm, key, iv);
try {
let decrypted = decipher.update(encryptedString, "hex", "utf8");
decrypted += decipher.final("utf8");
return decrypted;
} catch (error) {
return null;
}
};
module.exports = decrypt;

View File

@ -0,0 +1,15 @@
// @ts-check
/**
* Regular expression to match default fields
*
* @description Regular expression to match default fields
*/
const defaultFieldsRegexp =
/^id$|^uuid$|^date_created$|^date_created_code$|^date_created_timestamp$|^date_updated$|^date_updated_code$|^date_updated_timestamp$/;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
module.exports = defaultFieldsRegexp;

View File

@ -0,0 +1,43 @@
// @ts-check
const { scryptSync, createCipheriv } = require("crypto");
const { Buffer } = require("buffer");
const serverError = require("./serverError");
/**
* @async
* @param {string} data
* @param {string} [encryptionKey]
* @param {string} [encryptionSalt]
* @returns {string | null}
*/
const encrypt = (data, encryptionKey, encryptionSalt) => {
const algorithm = "aes-192-cbc";
const password = encryptionKey
? encryptionKey
: process.env.DSQL_ENCRYPTION_PASSWORD || "";
/** ********************* Generate key */
const salt = encryptionSalt
? encryptionSalt
: process.env.DSQL_ENCRYPTION_SALT || "";
let key = scryptSync(password, salt, 24);
let iv = Buffer.alloc(16, 0);
// @ts-ignore
const cipher = createCipheriv(algorithm, key, iv);
/** ********************* Encrypt data */
try {
let encrypted = cipher.update(data, "utf8", "hex");
encrypted += cipher.final("hex");
return encrypted;
} catch (/** @type {any} */ error) {
serverError({
component: "encrypt",
message: error.message,
});
return null;
}
};
module.exports = encrypt;

View File

@ -0,0 +1,78 @@
// @ts-check
const DSQL_USER_DB_HANDLER = require("../../utils/backend/global-db/DSQL_USER_DB_HANDLER");
const parseDbResults = require("./parseDbResults");
const serverError = require("./serverError");
/**
*
* @param {object} param0
* @param {string} param0.queryString
* @param {string} param0.database
* @param {boolean} [param0.local]
* @param {import("../../types").DSQL_TableSchemaType | null} [param0.tableSchema]
* @param {string[]} [param0.queryValuesArray]
* @returns
*/
module.exports = async function fullAccessDbHandler({
queryString,
database,
tableSchema,
queryValuesArray,
local,
}) {
/**
* Declare variables
*
* @description Declare "results" variable
*/
let results;
/**
* Fetch from db
*
* @description Fetch data from db if no cache
*/
try {
/** ********************* Run Query */
results = await DSQL_USER_DB_HANDLER({
paradigm: "Full Access",
database,
queryString,
queryValues: queryValuesArray,
});
////////////////////////////////////////
} catch (/** @type {any} */ error) {
////////////////////////////////////////
serverError({
component: "fullAccessDbHandler",
message: error.message,
});
/**
* Return error
*/
return error.message;
}
/**
* Return results
*
* @description Return results add to cache if "req" param is passed
*/
if (results && tableSchema) {
const unparsedResults = results;
const parsedResults = await parseDbResults({
unparsedResults: unparsedResults,
tableSchema: tableSchema,
});
return parsedResults;
} else if (results) {
return results;
} else {
return null;
}
};

View File

@ -0,0 +1,12 @@
// @ts-check
const sanitizeHtmlOptions = {
allowedTags: ["b", "i", "em", "strong", "a", "p", "span", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6", "img", "div", "button", "pre", "code", "br"],
allowedAttributes: {
a: ["href"],
img: ["src", "alt", "width", "height", "class", "style"],
"*": ["style", "class"],
},
};
module.exports = sanitizeHtmlOptions;

View File

@ -0,0 +1,59 @@
// @ts-check
const fs = require("fs");
const serverError = require("./serverError");
const NO_DB_HANDLER = require("../../../package-shared/utils/backend/global-db/NO_DB_HANDLER");
/**
* Create database from Schema Function
* ==============================================================================
* @param {string} queryString - Query String
* @returns {Promise<any>}
*/
module.exports = async function noDatabaseDbHandler(queryString) {
process.env.NODE_ENV?.match(/dev/) &&
fs.appendFileSync(
"./.tmp/sqlQuery.sql",
queryString + "\n" + Date() + "\n\n\n",
"utf8"
);
/**
* Declare variables
*
* @description Declare "results" variable
*/
let results;
/**
* Fetch from db
*
* @description Fetch data from db if no cache
*/
try {
/** ********************* Run Query */
results = await NO_DB_HANDLER(queryString);
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
} catch (/** @type {any} */ error) {
serverError({
component: "noDatabaseDbHandler",
message: error.message,
});
console.log("ERROR in noDatabaseDbHandler =>", error.message);
}
/**
* Return results
*
* @description Return results add to cache if "req" param is passed
*/
if (results) {
return results;
} else {
return null;
}
};

View File

@ -0,0 +1,76 @@
// @ts-check
const decrypt = require("./decrypt");
const defaultFieldsRegexp = require("./defaultFieldsRegexp");
/**
* Parse Database results
* ==============================================================================
* @description this function takes a database results array gotten from a DB handler
* function, decrypts encrypted fields, and returns an updated array with no encrypted
* fields
*
* @param {object} params - Single object params
* @param {any[]} params.unparsedResults - Array of data objects containing Fields(keys)
* and corresponding values of the fields(values)
* @param {import("../../types").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @returns {Promise<object[]|null>}
*/
module.exports = async function parseDbResults({
unparsedResults,
tableSchema,
}) {
/**
* Declare variables
*
* @description Declare "results" variable
*/
let parsedResults = [];
try {
/**
* Declare variables
*
* @description Declare "results" variable
*/
for (let pr = 0; pr < unparsedResults.length; pr++) {
let result = unparsedResults[pr];
let resultFieldNames = Object.keys(result);
for (let i = 0; i < resultFieldNames.length; i++) {
const resultFieldName = resultFieldNames[i];
let resultFieldSchema = tableSchema?.fields[i];
if (resultFieldName?.match(defaultFieldsRegexp)) {
continue;
}
let value = result[resultFieldName];
if (typeof value !== "number" && !value) {
// parsedResults.push(result);
continue;
}
if (resultFieldSchema?.encrypted) {
if (value?.match(/./)) {
result[resultFieldName] = decrypt(value);
}
}
}
parsedResults.push(result);
}
/**
* Declare variables
*
* @description Declare "results" variable
*/
return parsedResults;
} catch (/** @type {any} */ error) {
console.log("ERROR in parseDbResults Function =>", error.message);
return unparsedResults;
}
};

View File

@ -0,0 +1,31 @@
// @ts-check
const { createHmac } = require("crypto");
//
/**
* # Password Hash function
* @param {string} password
* @returns
*/
function hashPassword(password) {
const hmac = createHmac(
"sha512",
process.env.DSQL_ENCRYPTION_PASSWORD || ""
);
hmac.update(password);
let hashed = hmac.digest("base64");
return hashed;
}
exports.hashPassword = hashPassword;
// export const comparePasswords = async (password) => {
// const hmac = createHmac("sha512", process.env.DSQL_ENCRYPTION_PASSWORD);
// hmac.update(password);
// let hashed = hmac.digest("base64");
// let dbPass = await global.DB_HANDLER(`SELECT * FROM users WHERE password = '${hashed}'`);
// console.log(dbPass);
// return dbPass;
// };

View File

@ -0,0 +1,55 @@
// @ts-check
/**
* ==============================================================================
* Imports
* ==============================================================================
*/
const fs = require("fs");
// const handleNodemailer = require("./handleNodemailer");
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/** ****************************************************************************** */
/**
* ==============================================================================
* Main Function
* ==============================================================================
* @param {{
* user?: { id?: number | string, first_name?: string, last_name?: string, email?: string } & *,
* message: string,
* component?: string,
* noMail?: boolean,
* }} params - user id
*
* @returns {Promise<void>}
*/
module.exports = async function serverError({
user,
message,
component,
noMail,
}) {
const log = `🚀 SERVER ERROR ===========================\nUser Id: ${
user?.id
}\nUser Name: ${user?.first_name} ${user?.last_name}\nUser Email: ${
user?.email
}\nError Message: ${message}\nComponent: ${component}\nDate: ${Date()}\n========================================`;
if (!fs.existsSync(`./.tmp/error.log`)) {
fs.writeFileSync(`./.tmp/error.log`, "", "utf-8");
}
const initialText = fs.readFileSync(`./.tmp/error.log`, "utf-8");
fs.writeFileSync(`./.tmp/error.log`, log);
fs.appendFileSync(`./.tmp/error.log`, `\n\n\n\n\n${initialText}`);
};
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////

View File

@ -0,0 +1,38 @@
// @ts-check
const { IncomingMessage } = require("http");
const decrypt = require("./decrypt");
const parseCookies = require("../../../utils/functions/parseCookies");
/**
* @async
* @param {IncomingMessage} req - https request object
*
* @returns {Promise<({ email: string, password: string, authKey: string, logged_in_status: boolean, date: number } | null)>}
*/
module.exports = async function (req) {
const cookies = parseCookies({ request: req });
/** ********************* Check for existence of required cookie */
if (!cookies?.datasquirelSuAdminUserAuthKey) {
return null;
}
/** ********************* Grab the payload */
let userPayload = decrypt(cookies.datasquirelSuAdminUserAuthKey);
/** ********************* Return if no payload */
if (!userPayload) return null;
/** ********************* Parse the payload */
let userObject = JSON.parse(userPayload);
if (userObject.password !== process.env.DSQL_USER_KEY) return null;
if (userObject.authKey !== process.env.DSQL_SPECIAL_KEY) return null;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/** ********************* return user object */
return userObject;
};

View File

@ -0,0 +1,116 @@
// @ts-check
const fs = require("fs");
const parseDbResults = require("./parseDbResults");
const serverError = require("./serverError");
const DB_HANDLER = require("../../utils/backend/global-db/DB_HANDLER");
const DSQL_USER_DB_HANDLER = require("../../utils/backend/global-db/DSQL_USER_DB_HANDLER");
/**
* DB handler for specific database
* ==============================================================================
* @async
* @param {object} params - Single object params
* @param {string} params.queryString - SQL string
* @param {*[]} [params.queryValuesArray] - Values Array
* @param {string} [params.database] - Database name
* @param {import("../../types").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @returns {Promise<any>}
*/
module.exports = async function varDatabaseDbHandler({
queryString,
queryValuesArray,
database,
tableSchema,
}) {
/**
* Declare variables
*
* @description Declare "results" variable
*/
const isMaster = database?.match(/^datasquirel$/) ? true : false;
/** @type {any} */
const FINAL_DB_HANDLER = isMaster ? DB_HANDLER : DSQL_USER_DB_HANDLER;
let results;
/**
* Fetch from db
*
* @description Fetch data from db if no cache
*/
try {
if (
queryString &&
queryValuesArray &&
Array.isArray(queryValuesArray) &&
queryValuesArray[0]
) {
results = isMaster
? await FINAL_DB_HANDLER(queryString, queryValuesArray)
: await FINAL_DB_HANDLER({
paradigm: "Full Access",
database,
queryString,
queryValues: queryValuesArray,
});
} else {
results = isMaster
? await FINAL_DB_HANDLER(queryString)
: await FINAL_DB_HANDLER({
paradigm: "Full Access",
database,
queryString,
});
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
} catch (/** @type {any} */ error) {
serverError({
component: "varDatabaseDbHandler/lines-29-32",
message: error.message,
});
}
/**
* Return results
*
* @description Return results add to cache if "req" param is passed
*/
if (results && tableSchema) {
try {
const unparsedResults = results;
const parsedResults = await parseDbResults({
unparsedResults: unparsedResults,
tableSchema: tableSchema,
});
return parsedResults;
} catch (/** @type {any} */ error) {
console.log(
"\x1b[31mvarDatabaseDbHandler ERROR\x1b[0m =>",
database,
error
);
serverError({
component: "varDatabaseDbHandler/lines-52-53",
message: error.message,
});
return null;
}
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
} else if (results) {
return results;
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
} else {
return null;
}
};

View File

@ -0,0 +1,74 @@
// @ts-check
const fs = require("fs");
const serverError = require("./serverError");
const parseDbResults = require("./parseDbResults");
const DSQL_USER_DB_HANDLER = require("../../utils/backend/global-db/DSQL_USER_DB_HANDLER");
/**
*
* @param {object} param0
* @param {string} param0.queryString
* @param {string} param0.database
* @param {string[]} [param0.queryValuesArray]
* @param {import("../../types").DSQL_TableSchemaType} [param0.tableSchema]
* @returns
*/
module.exports = async function varReadOnlyDatabaseDbHandler({
queryString,
database,
queryValuesArray,
tableSchema,
}) {
/**
* Declare variables
*
* @description Declare "results" variable
*/
let results;
/**
* Fetch from db
*
* @description Fetch data from db if no cache
*/
try {
results = await DSQL_USER_DB_HANDLER({
paradigm: "Read Only",
database,
queryString,
queryValues: queryValuesArray,
});
////////////////////////////////////////
} catch (/** @type {any} */ error) {
////////////////////////////////////////
serverError({
component: "varReadOnlyDatabaseDbHandler",
message: error.message,
noMail: true,
});
/**
* Return error
*/
return error.message;
}
/**
* Return results
*
* @description Return results add to cache if "req" param is passed
*/
if (results) {
const unparsedResults = results;
const parsedResults = await parseDbResults({
unparsedResults: unparsedResults,
tableSchema: tableSchema,
});
return parsedResults;
} else {
return null;
}
};

View File

@ -1,5 +1,6 @@
import http from "http"; import http from "http";
import { Editor } from "tinymce";
export type DSQL_DatabaseFullName = string; export type DSQL_DatabaseFullName = string;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -139,6 +140,7 @@ export interface DSQL_MYSQL_FOREIGN_KEYS_Type {
//////////////////////////////////////// ////////////////////////////////////////
export interface DSQL_MYSQL_user_databases_Type { export interface DSQL_MYSQL_user_databases_Type {
id: number;
user_id: number; user_id: number;
db_full_name: string; db_full_name: string;
db_name: string; db_name: string;
@ -147,6 +149,17 @@ export interface DSQL_MYSQL_user_databases_Type {
db_description: string; db_description: string;
active_clone: number; active_clone: number;
active_clone_parent_db: string; active_clone_parent_db: string;
remote_connected?: number;
remote_db_full_name?: string;
remote_connection_host?: string;
remote_connection_key?: string;
remote_connection_type?: string;
user_priviledge?: string;
date_created?: string;
image_thumbnail?: string;
first_name?: string;
last_name?: string;
email?: string;
} }
export interface PackageUserLoginRequestBody { export interface PackageUserLoginRequestBody {
@ -370,3 +383,716 @@ export interface PostInsertReturn {
protocol41: boolean; protocol41: boolean;
changedRows: number; changedRows: number;
} }
export interface UserType {
id: number;
stripe_id?: string;
first_name: string;
last_name: string;
email: string;
bio?: string;
username?: string;
image: string;
image_thumbnail: string;
social_id?: string;
verification_status?: number;
social_platform?: string;
social_login?: number;
date?: number;
phone?: number | string;
csrf_k: string;
logged_in_status: boolean;
}
export interface ApiKeyDef {
name: string;
scope: string;
date_created: string;
apiKeyPayload: string;
}
export interface MetricsType {
dbCount: number;
tablesCount: number;
mediaCount: number;
apiKeysCount: number;
}
export interface DashboardContextType {
user?: UserType;
databases?: DSQL_MYSQL_user_databases_Type[];
setTargetDatabase?: React.Dispatch<
React.SetStateAction<DSQL_MYSQL_user_databases_Type>
>;
targetDatabase?: DSQL_MYSQL_user_databases_Type;
metrics?: MetricsType;
}
export interface AddDbContextType {
user?: UserType;
databases?: DSQL_MYSQL_user_databases_Type[];
dbImage?: string | null | ImageObjectType;
setDbImage?: React.Dispatch<
React.SetStateAction<string | null | ImageObjectType>
>;
query?: any;
duplicateDb?: DSQL_MYSQL_user_databases_Type;
}
export interface EditDbContextType {
user?: UserType;
database?: DSQL_MYSQL_user_databases_Type;
dbImage?: string | null | ImageObjectType;
setDbImage?: React.Dispatch<
React.SetStateAction<string | null | ImageObjectType>
>;
}
export interface RichTextEditorsRefArray {
fieldName: string;
ref: React.MutableRefObject<Editor>;
}
export interface JSONTextEditorsRefArray {
fieldName: string;
ref: React.MutableRefObject<AceAjax.Editor>;
}
export interface TableEntriesContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
dbSchemaData: DSQL_DatabaseSchemaType[];
entries: any[];
targetEntry?: any;
setTargetEntry: React.Dispatch<React.SetStateAction<any>>;
richTextEditors: React.MutableRefObject<RichTextEditorsRefArray[]>;
jsonTextEditors: React.MutableRefObject<JSONTextEditorsRefArray[]>;
query?: any;
confirmedDelegetedUser?: any;
activeEntries: any[] | null;
setActiveEntries: React.Dispatch<React.SetStateAction<any[] | null>>;
targetField: React.MutableRefObject<string>;
searchTerm: React.MutableRefObject<string | null>;
entriesCount: number;
}
export interface AddEntryContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
dbSchemaData: DSQL_DatabaseSchemaType[];
richTextEditors: React.MutableRefObject<RichTextEditorsRefArray[]>;
jsonTextEditors: React.MutableRefObject<JSONTextEditorsRefArray[]>;
query: any;
duplicateEntry?: any;
confirmedDelegetedUser: any;
}
export interface UserDatabasesContextType {
user: UserType;
users: any[];
targetUser: any;
setTargetUser: React.Dispatch<React.SetStateAction<any>>;
databases: DSQL_MYSQL_user_databases_Type[];
}
export interface SettingsPageContextType {
user: UserType;
image: any;
setImage: React.Dispatch<React.SetStateAction<any>>;
activeUser: any;
}
export interface MediaFolderPageContextType {
user: UserType;
media: any[];
targetMedia: any;
setTargetMedia: React.Dispatch<React.SetStateAction<any>>;
folders: any[];
query: any;
staticHost: string;
folder: string;
}
export interface TablesContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
tables: MYSQL_user_database_tables_table_def[];
targetTable: MYSQL_user_database_tables_table_def | null;
setTargetTable: React.Dispatch<
React.SetStateAction<MYSQL_user_database_tables_table_def | null>
>;
query: any;
confirmedDelegetedUser: any;
}
export interface EditTableContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
tableFields: DSQL_FieldSchemaType[];
setTableFields: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType[]>
>;
targetField: DSQL_FieldSchemaType | null;
setTargetField: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType | null>
>;
pageRefresh: number;
setPageRefresh: React.Dispatch<React.SetStateAction<number>>;
refreshFieldsListRef: React.MutableRefObject<
React.Dispatch<React.SetStateAction<number>> | undefined
>;
dbSchemaData: DSQL_DatabaseSchemaType[];
query: any;
confirmedDelegetedUser: any;
}
export interface SingleDatabaseContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
tables: MYSQL_user_database_tables_table_def[];
targetTable: MYSQL_user_database_tables_table_def | null;
setTargetTable: React.Dispatch<
React.SetStateAction<MYSQL_user_database_tables_table_def | null>
>;
query: any;
confirmedDelegetedUser: any;
}
export interface ApiKeysContextType {
user: UserType;
apiKeys: any[];
setApiKeys: React.Dispatch<React.SetStateAction<any[]>>;
targetApiKey: any | null;
setTargetApiKey: React.Dispatch<React.SetStateAction<any | null>>;
newApiKey: any | null;
setNewApiKey: React.Dispatch<React.SetStateAction<any | null>>;
}
export interface LoginFormContextType {
user?: UserType | null;
loading: boolean;
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
alert: string | boolean;
setAlert: React.Dispatch<React.SetStateAction<string | boolean>>;
}
export interface CreateAccountContextType {
user?: UserType | null;
query: CreateAccountQueryType;
invitingUser: any;
}
export interface CreateAccountQueryType {
invite?: number;
database_access?: string;
priviledge?: string;
email?: string;
}
export interface DocsAsidePageObject {
id: number;
title: string;
slug: string;
parent_id?: number;
level?: number;
}
export interface AllUserUsersContextType {
user: UserType;
users: MYSQL_delegated_users_table_def[];
targetUser: MYSQL_user_users_table_def | null;
setTargetUser: React.Dispatch<
React.SetStateAction<MYSQL_user_users_table_def | null>
>;
databases: DSQL_MYSQL_user_databases_Type[];
pendingInvitations: MYSQL_invitations_table_def[];
pendingInvitationsReceived: any[];
adminUsers: any[];
invitedAccounts: any[];
}
export interface AddSocialLoginContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
query: any;
socialLogins: SocialLoginObjectType[];
}
export interface DelegatedDbContextType {
user: UserType;
users: MYSQL_user_users_table_def[];
targetUser: MYSQL_user_users_table_def | null;
setTargetUser: React.Dispatch<
React.SetStateAction<MYSQL_user_users_table_def | null>
>;
database: DSQL_MYSQL_user_databases_Type;
}
export interface AddUserUserContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
query: any;
confirmedDelegetedUser: any;
}
export interface UserUsersContextType {
user: UserType;
users: MYSQL_user_users_table_def[];
targetUser: MYSQL_user_users_table_def;
setTargetUser: React.Dispatch<
React.SetStateAction<MYSQL_user_users_table_def | null>
>;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
dbSchemaData: DSQL_DatabaseSchemaType[];
query: any;
confirmedDelegetedUser: any;
}
export interface DatabaseSingleUserContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
singleUser: MYSQL_user_users_table_def;
table: DSQL_TableSchemaType;
dbSchemaData: DSQL_DatabaseSchemaType[];
query: any;
confirmedDelegetedUser: any;
}
export interface SingleUserUserContextType {
user: UserType;
singleUser: MYSQL_user_users_table_def;
}
export interface AddUserContextType {
user: UserType;
users: MYSQL_delegated_users_table_def[];
databases: DSQL_MYSQL_user_databases_Type[];
query: any;
}
export interface MediaContextType {
user: UserType;
media: MYSQL_user_media_table_def[];
targetMedia: MYSQL_user_media_table_def | null;
setTargetMedia: React.Dispatch<
React.SetStateAction<MYSQL_user_media_table_def | null>
>;
folders: string[];
staticHost: string;
}
export interface MediaSubFolderContextType {
user: UserType;
media: MYSQL_user_media_table_def[];
targetMedia: MYSQL_user_media_table_def | null;
setTargetMedia: React.Dispatch<
React.SetStateAction<MYSQL_user_media_table_def | null>
>;
folders: string[];
query: any;
folder: string;
staticHost: string;
}
export interface FieldsContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
dbSchemaData: DSQL_DatabaseSchemaType[];
targetField: DSQL_FieldSchemaType | null;
setTargetField: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType | null>
>;
refreshFieldsListRef: React.MutableRefObject<
React.Dispatch<React.SetStateAction<number>> | undefined
>;
tableFields: DSQL_FieldSchemaType[];
setTableFields: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType[]>
>;
updateTableAfterFieldsUpdateFunction: () => void;
query: any;
confirmedDelegetedUser: any;
}
export interface SingleTableContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
tableRecord: MYSQL_user_database_tables_table_def;
tableFields: DSQL_FieldSchemaType[];
setTableFields: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType[]>
>;
tableIndexes: DSQL_IndexSchemaType[];
setTableIndexes: React.Dispatch<
React.SetStateAction<DSQL_IndexSchemaType[]>
>;
dbSchemaData: DSQL_DatabaseSchemaType[];
entries: any[];
targetEntry: any;
setTargetEntry: React.Dispatch<React.SetStateAction<any>>;
richTextEditors: React.MutableRefObject<RichTextEditorsRefArray[]>;
jsonTextEditors: React.MutableRefObject<JSONTextEditorsRefArray[]>;
query: any;
confirmedDelegetedUser: any;
targetField: DSQL_FieldSchemaType | null;
setTargetField: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType | null>
>;
refreshFieldsListRef: React.MutableRefObject<
React.Dispatch<React.SetStateAction<number>>
>;
updateTableAfterFieldsUpdateFunction: () => void;
entriesCount: number;
}
export interface SingleEntryContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
table: DSQL_TableSchemaType;
dbSchemaData: DSQL_DatabaseSchemaType[];
entry: any;
targetEntry: any;
setTargetEntry: React.Dispatch<React.SetStateAction<any>>;
richTextEditors: React.MutableRefObject<RichTextEditorsRefArray[]>;
jsonTextEditors: React.MutableRefObject<JSONTextEditorsRefArray[]>;
query: any;
confirmedDelegetedUser: any;
prevEntry: any;
nextEntry: any;
}
export interface UserSchemaContextType {
user: UserType;
dbSchemaData: DSQL_DatabaseSchemaType[];
}
export interface ConnectContextType {
user: UserType;
query: any;
mariadbUserCred: MariaDBUserCredType;
mariadbUsers: MYSQL_mariadb_users_table_def[];
targetMariadbUser: MYSQL_mariadb_users_table_def | null;
setTargetMariadbUser: React.Dispatch<
React.SetStateAction<MYSQL_mariadb_users_table_def | null>
>;
refresh: number;
setRefresh: React.Dispatch<React.SetStateAction<number>>;
}
export interface MYSQL_mariadb_users_table_def {
id?: number;
user_id?: number;
username?: string;
host?: string;
password?: string;
primary?: number;
grants?: string;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export interface DbContextType {
user?: UserType;
databases?: DSQL_MYSQL_user_databases_Type[];
targetDatabase?: DSQL_MYSQL_user_databases_Type;
setTargetDatabase?: React.Dispatch<
React.SetStateAction<DSQL_MYSQL_user_databases_Type>
>;
}
export interface MariaDBUserCredType {
mariadb_user?: string;
mariadb_host?: string;
mariadb_pass?: string;
}
export interface AddTableContextType {
user: UserType;
dbSchemaData: DSQL_DatabaseSchemaType[];
database: DSQL_MYSQL_user_databases_Type;
tables: DSQL_TableSchemaType[];
tableFields: DSQL_FieldSchemaType[];
setTableFields: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType[]>
>;
targetField: DSQL_FieldSchemaType | null;
setTargetField: React.Dispatch<
React.SetStateAction<DSQL_FieldSchemaType | null>
>;
pageRefresh: number | null;
setPageRefresh: React.Dispatch<React.SetStateAction<number>>;
refreshFieldsListRef: React.MutableRefObject<
React.Dispatch<React.SetStateAction<number>>
>;
query: any;
}
export interface DbSchemaContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
dbImage: string;
setDbImage: React.Dispatch<React.SetStateAction<string>>;
dbSchemaData: DSQL_DatabaseSchemaType[];
tables: any[];
}
export interface DbShellContextType {
user?: UserType;
database?: DSQL_MYSQL_user_databases_Type;
dbImage?: string;
setDbImage?: React.Dispatch<React.SetStateAction<string>>;
dbSchemaData?: DSQL_DatabaseSchemaType[];
tables?: any[];
}
export interface DbConnectContextType {
user: UserType;
database: DSQL_MYSQL_user_databases_Type;
targetDbSchema: DSQL_DatabaseSchemaType;
query: any;
}
export interface ImageObjectType {
imageName?: string;
mimeType?: string;
imageSize?: number;
private?: boolean;
imageBase64?: string;
imageBase64Full?: string;
}
export interface FileObjectType {
fileName?: string;
private?: boolean;
fileType?: string;
fileSize?: number;
fileBase64?: string;
fileBase64Full?: string;
}
export interface SocialLoginObjectType {
platform?: string;
paradigm?: string;
clientId?: string;
clientSecret?: string;
callbackUrl?: string;
domain1?: string;
domain2?: string;
domain3?: string;
}
export interface DbConnectType {
url: string;
key: string;
database: DSQL_MYSQL_user_databases_Type;
dbSchema: DSQL_DatabaseSchemaType;
type: "pull" | "push";
remoteDbs?: DSQL_DatabaseSchemaType[];
targetDb?: DSQL_DatabaseSchemaType;
}
export interface MYSQL_MediaType {
id?: number;
user_id?: number;
media_name?: string;
folder?: string;
media_url?: string;
media_thumbnail_url?: string;
media_type?: string;
width?: string;
height?: string;
size?: string;
private?: string;
}
export interface UserFileObject {
title?: string;
path?: string;
data?: string;
}
export interface UserFileObject2 {
type?: string;
name?: string;
root?: string;
content?: UserFileObject2[];
}
export interface MYSQL_user_users_table_def {
id?: number;
user_id?: number;
invited_user_id?: number;
database?: string;
database_access?: string;
first_name?: string;
last_name?: string;
email?: string;
username?: string;
password?: string;
phone?: string;
user_type?: string;
user_priviledge?: string;
image?: string;
image_thumbnail?: string;
city?: string;
state?: string;
country?: string;
zip_code?: string;
address?: string;
social_login?: number;
social_platform?: string;
social_id?: string;
verification_status?: number;
more_user_data?: string;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
inviteeFirstName?: string;
inviteeLastName?: string;
inviteeEmail?: string;
inviteeImage?: string;
}
export interface MYSQL_user_database_tables_table_def {
id?: number;
user_id?: number;
db_id?: number;
db_slug?: string;
table_name?: string;
table_slug?: string;
table_description?: string;
child_table?: number;
child_table_parent_database?: string;
child_table_parent_table?: string;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export interface MYSQL_user_media_table_def {
id?: number;
user_id?: number;
media_name?: string;
folder?: string;
media_url?: string;
media_thumbnail_url?: string;
media_path?: string;
media_thumbnail_path?: string;
media_type?: string;
width?: number;
height?: number;
size?: number;
private?: number;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export interface MYSQL_delegated_users_table_def {
id?: number;
user_id?: number;
delegated_user_id?: number;
permissions?: string;
permission_level_code?: number;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export interface MYSQL_invitations_table_def {
id?: number;
inviting_user_id?: number;
invited_user_email?: string;
invitation_status?: string;
database_access?: string;
priviledge?: string;
db_tables_data?: string;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export interface MYSQL_docs_pages_table_def {
id?: number;
title?: string;
slug?: string;
description?: string;
content?: string;
text_content?: string;
level?: number;
page_order?: number;
parent_id?: number;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export interface MYSQL_delegated_user_tables_table_def {
id?: number;
delegated_user_id?: number;
root_user_id?: number;
database?: string;
table?: string;
priviledge?: string;
date_created?: string;
date_created_code?: number;
date_created_timestamp?: string;
date_updated?: string;
date_updated_code?: number;
date_updated_timestamp?: string;
}
export type ApiKeyObject = {
user_id: string | number;
full_access?: boolean;
sign: string;
date_code: number;
target_database?: string;
target_table?: string;
};
export type AddApiKeyRequestBody = {
api_key_name: string;
api_key_slug: string;
api_key_scope?: "fullAccess" | "readOnly";
target_database?: string;
target_table?: string;
};
export type CheckApiCredentialsFn = (
param: CheckApiCredentialsFnParam
) => ApiKeyObject | null | undefined;
export type CheckApiCredentialsFnParam = {
key: string;
database?: string;
table?: string;
};

View File

@ -153,6 +153,7 @@
/** /**
* @typedef {object} DSQL_MYSQL_user_databases_Type * @typedef {object} DSQL_MYSQL_user_databases_Type
* @property {number} id
* @property {number} user_id - User Id * @property {number} user_id - User Id
* @property {string} db_full_name - Database full name => eg. (dataasquirel_user_2_new_database) * @property {string} db_full_name - Database full name => eg. (dataasquirel_user_2_new_database)
* @property {string} db_name - Database name with spaces => eg. (New Database) * @property {string} db_name - Database name with spaces => eg. (New Database)
@ -161,6 +162,15 @@
* @property {string} db_description - Database description * @property {string} db_description - Database description
* @property {number} active_clone - is Database active clone => 0 or 1 * @property {number} active_clone - is Database active clone => 0 or 1
* @property {string} active_clone_parent_db - Database parent db full name => eg. "datasquirel_user_7_wexculture" * @property {string} active_clone_parent_db - Database parent db full name => eg. "datasquirel_user_7_wexculture"
* @property {number} [remote_connected]
* @property {string} [remote_db_full_name]
* @property {string} [remote_connection_host]
* @property {string} [user_priviledge]
* @property {string} [date_created]
* @property {string} [image_thumbnail]
* @property {string} [first_name]
* @property {string} [last_name]
* @property {string} [email]
*/ */
/** /**
@ -426,3 +436,731 @@ const http = require("http");
* @property {boolean} protocol41 * @property {boolean} protocol41
* @property {number} changedRows * @property {number} changedRows
*/ */
// @ts-check
const { Editor } = require("tinymce");
/**
* @typedef {object} UserType
* @property {number} id - user id (number)
* @property {string} [stripe_id] - Stripe ID for payments
* @property {string} first_name - User First Name
* @property {string} last_name - User Last Name
* @property {string} email - User Email Address
* @property {string} [bio] - User Description HTML
* @property {string} [username] - User Username
* @property {string} image - User Full Image
* @property {string} image_thumbnail - User Image Thumbnail
* @property {string} [social_id] - User Social id if available
* @property {number} [verification_status] - 0 or 1 or 2
* @property {string} [social_platform] - Google or Facebook or Github
* @property {number} [social_login] - 0 or 1 => is this user a social user(1) or not(0)
* @property {number} [date] - Creation Date
* @property {number | string} [phone]
* @property {string} csrf_k - CSRF key
* @property {boolean} logged_in_status - Is user logged in or not
*/
/**
* @typedef {object} ApiKeyDef
* @property {string} name
* @property {string} scope
* @property {string} date_created
* @property {string} apiKeyPayload
*/
/**
* @typedef {object} MetricsType
* @property {number} dbCount
* @property {number} tablesCount
* @property {number} mediaCount
* @property {number} apiKeysCount
*/
/**
* @typedef {object} DashboardContextType
* @property {UserType} [user]
* @property {DSQL_MYSQL_user_databases_Type[]} [databases]
* @property {React.Dispatch<React.SetStateAction<DSQL_MYSQL_user_databases_Type>>} [setTargetDatabase]
* @property {DSQL_MYSQL_user_databases_Type} [targetDatabase]
* @property {MetricsType} [metrics]
*/
/**
* @typedef {object} AddDbContextType
* @property {UserType} [user]
* @property {DSQL_MYSQL_user_databases_Type[]} [databases]
* @property {string | null | ImageObjectType} [dbImage]
* @property {React.Dispatch<React.SetStateAction<string | null | ImageObjectType>>} [setDbImage]
* @property {*} [query]
* @property {DSQL_MYSQL_user_databases_Type} [duplicateDb]
*/
/**
* @typedef {object} EditDbContextType
* @property {UserType} [user]
* @property {DSQL_MYSQL_user_databases_Type} [database]
* @property {string | null | ImageObjectType} [dbImage]
* @property {React.Dispatch<React.SetStateAction<string | null | ImageObjectType>>} [setDbImage]
*/
/**
* @typedef {object} RichTextEditorsRefArray
* @property {string} fieldName
* @property {React.MutableRefObject<Editor>} ref
*/
/**
* @typedef {object} JSONTextEditorsRefArray
* @property {string} fieldName
* @property {React.MutableRefObject<AceAjax.Editor>} ref
*/
/**
* @typedef {object} TableEntriesContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any[]} entries
* @property {any} [targetEntry]
* @property {React.Dispatch<React.SetStateAction<any>>} setTargetEntry
* @property {React.MutableRefObject<RichTextEditorsRefArray[]>} richTextEditors
* @property {React.MutableRefObject<JSONTextEditorsRefArray[]>} jsonTextEditors
* @property {any} [query]
* @property {any} [confirmedDelegetedUser]
* @property {any[] | null} activeEntries
* @property {React.Dispatch<React.SetStateAction<any[] | null>>} setActiveEntries
* @property {React.MutableRefObject<string>} targetField
* @property {React.MutableRefObject<string|null>} searchTerm
* @property {number} entriesCount
*/
/**
* @typedef {object} AddEntryContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {React.MutableRefObject<RichTextEditorsRefArray[]>} richTextEditors
* @property {React.MutableRefObject<JSONTextEditorsRefArray[]>} jsonTextEditors
* @property {any} query
* @property {any} [duplicateEntry]
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} UserDatabasesContextType
* @property {UserType} user
* @property {any[]} users
* @property {any} targetUser
* @property {React.Dispatch<React.SetStateAction<any>>} setTargetUser
* @property {DSQL_MYSQL_user_databases_Type[]} databases
*/
/**
* @typedef {object} SettingsPageContextType
* @property {UserType} user
* @property {any} image
* @property {React.Dispatch<React.SetStateAction<any>>} setImage
* @property {any} activeUser
*/
/**
* @typedef {object} MediaFolderPageContextType
* @property {UserType} user
* @property {any[]} media
* @property {any} targetMedia
* @property {React.Dispatch<React.SetStateAction<any>>} setTargetMedia
* @property {any[]} folders
* @property {any} query
* @property {string} staticHost
* @property {string} folder
*/
/**
* @typedef {object} TablesContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {MYSQL_user_database_tables_table_def[]} tables
* @property {MYSQL_user_database_tables_table_def | null} targetTable
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_database_tables_table_def | null>>} setTargetTable
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} EditTableContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {DSQL_FieldSchemaType[]} tableFields
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType[]>>} setTableFields
* @property {DSQL_FieldSchemaType | null} targetField
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType | null>>} setTargetField
* @property {number} pageRefresh
* @property {React.Dispatch<React.SetStateAction<number>>} setPageRefresh
* @property {React.MutableRefObject<React.Dispatch<React.SetStateAction<number>> | undefined>} refreshFieldsListRef
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} SingleDatabaseContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {MYSQL_user_database_tables_table_def[]} tables
* @property {MYSQL_user_database_tables_table_def | null} targetTable
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_database_tables_table_def | null>>} setTargetTable
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} ApiKeysContextType
* @property {UserType} user
* @property {any[]} apiKeys
* @property {React.Dispatch<React.SetStateAction<any[]>>} setApiKeys
* @property {any | null} targetApiKey
* @property {React.Dispatch<React.SetStateAction<any | null>>} setTargetApiKey
* @property {any | null} newApiKey
* @property {React.Dispatch<React.SetStateAction<any | null>>} setNewApiKey
*/
/**
* @typedef {object} LoginFormContextType
* @property {UserType | null} [user]
* @property {boolean} loading
* @property {React.Dispatch<React.SetStateAction<boolean>>} setLoading
* @property {string | boolean} alert
* @property {React.Dispatch<React.SetStateAction<string | boolean>>} setAlert
*/
/**
* @typedef {object} CreateAccountContextType
* @property {UserType | null} [user]
* @property {CreateAccountQueryType} query
* @property {any} invitingUser
*/
/**
* @typedef {object} CreateAccountQueryType
* @property {number} [invite]
* @property {string} [database_access]
* @property {string} [priviledge]
* @property {string} [email]
*/
/**
* @typedef {object} DocsAsidePageObject
* @property {number} id
* @property {string} title
* @property {string} slug
* @property {number} [parent_id]
* @property {number} [level]
*/
/**
* @typedef {object} AllUserUsersContextType
* @property {UserType} user
* @property {MYSQL_delegated_users_table_def[]} users
* @property {MYSQL_user_users_table_def | null} targetUser
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_users_table_def | null>>} setTargetUser
* @property {DSQL_MYSQL_user_databases_Type[]} databases
* @property {MYSQL_invitations_table_def[]} pendingInvitations
* @property {any[]} pendingInvitationsReceived
* @property {any[]} adminUsers
* @property {any[]} invitedAccounts
*/
/**
* @typedef {object} AddSocialLoginContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {any} query
* @property {SocialLoginObjectType[]} socialLogins
*/
/**
* @typedef {object} DelegatedDbContextType
* @property {UserType} user
* @property {MYSQL_user_users_table_def[]} users
* @property {MYSQL_user_users_table_def | null} targetUser
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_users_table_def | null>>} setTargetUser
* @property {DSQL_MYSQL_user_databases_Type} database
*/
/**
* @typedef {object} AddUserUserContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} UserUsersContextType
* @property {UserType} user
* @property {MYSQL_user_users_table_def[]} users
* @property {MYSQL_user_users_table_def} targetUser
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_users_table_def | null>>} setTargetUser
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} DatabaseSingleUserContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {MYSQL_user_users_table_def} singleUser
* @property {DSQL_TableSchemaType} table
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} SingleUserUserContextType
* @property {UserType} user
* @property {MYSQL_user_users_table_def} singleUser
*/
/**
* @typedef {object} AddUserContextType
* @property {UserType} user
* @property {MYSQL_delegated_users_table_def[]} users
* @property {DSQL_MYSQL_user_databases_Type[]} databases
* @property {any} query
*/
/**
* @typedef {object} MediaContextType
* @property {UserType} user
* @property {MYSQL_user_media_table_def[]} media
* @property {MYSQL_user_media_table_def | null} targetMedia
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_media_table_def | null>>} setTargetMedia
* @property {string[]} folders
* @property {string} staticHost
*/
/**
* @typedef {object} MediaSubFolderContextType
* @property {UserType} user
* @property {MYSQL_user_media_table_def[]} media
* @property {MYSQL_user_media_table_def | null} targetMedia
* @property {React.Dispatch<React.SetStateAction<MYSQL_user_media_table_def | null>>} setTargetMedia
* @property {string[]} folders
* @property {any} query
* @property {string} folder
* @property {string} staticHost
*/
/**
* @typedef {object} FieldsContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {DSQL_FieldSchemaType | null} targetField
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType | null>>} setTargetField
* @property {React.MutableRefObject<React.Dispatch<React.SetStateAction<number>> | undefined>} refreshFieldsListRef
* @property {DSQL_FieldSchemaType[]} tableFields
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType[]>>} setTableFields
* @property {()=>void} updateTableAfterFieldsUpdateFunction
* @property {any} query
* @property {any} confirmedDelegetedUser
*/
/**
* @typedef {object} SingleTableContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {MYSQL_user_database_tables_table_def} tableRecord
* @property {DSQL_FieldSchemaType[]} tableFields
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType[]>>} setTableFields
* @property {DSQL_IndexSchemaType[]} tableIndexes
* @property {React.Dispatch<React.SetStateAction<DSQL_IndexSchemaType[]>>} setTableIndexes
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any[]} entries
* @property {any} targetEntry
* @property {React.Dispatch<React.SetStateAction<any>>} setTargetEntry
* @property {React.MutableRefObject<RichTextEditorsRefArray[]>} richTextEditors
* @property {React.MutableRefObject<JSONTextEditorsRefArray[]>} jsonTextEditors
* @property {any} query
* @property {any} confirmedDelegetedUser
* @property {DSQL_FieldSchemaType | null} targetField
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType | null>>} setTargetField
* @property {React.MutableRefObject<React.Dispatch<React.SetStateAction<number>>>} refreshFieldsListRef
* @property {()=>void} updateTableAfterFieldsUpdateFunction
* @property {number} entriesCount
*/
/**
* @typedef {object} SingleEntryContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType} table
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any} entry
* @property {any} targetEntry
* @property {React.Dispatch<React.SetStateAction<any>>} setTargetEntry
* @property {React.MutableRefObject<RichTextEditorsRefArray[]>} richTextEditors
* @property {React.MutableRefObject<JSONTextEditorsRefArray[]>} jsonTextEditors
* @property {any} query
* @property {any} confirmedDelegetedUser
* @property {any} prevEntry
* @property {any} nextEntry
*/
/**
* @typedef {object} UserSchemaContextType
* @property {UserType} user
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
*/
/**
* @typedef {object} ConnectContextType
* @property {UserType} user
* @property {any} query
* @property {MariaDBUserCredType} mariadbUserCred
* @property {MYSQL_mariadb_users_table_def[]} mariadbUsers - All MariaDB Users including the primary User
* @property {MYSQL_mariadb_users_table_def | null} targetMariadbUser
* @property {React.Dispatch<React.SetStateAction<MYSQL_mariadb_users_table_def | null>>} setTargetMariadbUser
* @property {number} refresh
* @property {React.Dispatch<React.SetStateAction<number>>} setRefresh
*/
/**
* @typedef {object} MYSQL_mariadb_users_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {number} [user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {string} [username] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [host] - NULL=`YES` Key=`` Default=`%` Extra=``
* @property {string} [password] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [primary] - NULL=`YES` Key=`` Default=`0` Extra=``
* @property {string} [grants] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`current_timestamp()` Extra=``
* @property {string} [date_updated] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`current_timestamp()` Extra=`on update current_timestamp()`
*/
/**
* @typedef {object} DbContextType
* @property {UserType} [user]
* @property {DSQL_MYSQL_user_databases_Type[]} [databases]
* @property {DSQL_MYSQL_user_databases_Type} [targetDatabase]
* @property {React.Dispatch<React.SetStateAction<DSQL_MYSQL_user_databases_Type>>} [setTargetDatabase]
*/
/**
* @typedef {object} MariaDBUserCredType
* @property {string} [mariadb_user]
* @property {string} [mariadb_host]
* @property {string} [mariadb_pass]
*/
/**
* @typedef {object} AddTableContextType
* @property {UserType} user
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_TableSchemaType[]} tables
* @property {DSQL_FieldSchemaType[]} tableFields
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType[]>>} setTableFields
* @property {DSQL_FieldSchemaType | null} targetField
* @property {React.Dispatch<React.SetStateAction<DSQL_FieldSchemaType | null>>} setTargetField
* @property {number | null} pageRefresh
* @property {React.Dispatch<React.SetStateAction<number>>} setPageRefresh
* @property {React.MutableRefObject<React.Dispatch<React.SetStateAction<number>>>} refreshFieldsListRef
* @property {any} query
*/
/**
* @typedef {object} DbSchemaContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {string} dbImage
* @property {React.Dispatch<React.SetStateAction<string>>} setDbImage
* @property {DSQL_DatabaseSchemaType[]} dbSchemaData
* @property {any[]} tables
*/
/**
* @typedef {object} DbShellContextType
* @property {UserType} [user]
* @property {DSQL_MYSQL_user_databases_Type} [database]
* @property {string} [dbImage]
* @property {React.Dispatch<React.SetStateAction<string>>} [setDbImage]
* @property {DSQL_DatabaseSchemaType[]} [dbSchemaData]
* @property {any[]} [tables]
*/
/**
* @typedef {object} DbConnectContextType
* @property {UserType} user
* @property {DSQL_MYSQL_user_databases_Type} database
* @property {DSQL_DatabaseSchemaType} targetDbSchema
* @property {any} query
*/
/**
* @typedef {object} ImageObjectType
* @property {string} [imageName]
* @property {string} [mimeType]
* @property {number} [imageSize]
* @property {boolean} [private]
* @property {string} [imageBase64]
* @property {string} [imageBase64Full]
*/
/**
* @typedef {object} FileObjectType
* @property {string} [fileName]
* @property {boolean} [private]
* @property {string} [fileType]
* @property {number} [fileSize]
* @property {string} [fileBase64]
* @property {string} [fileBase64Full]
*/
/**
* @typedef {object} SocialLoginObjectType
* @property {string} [platform]
* @property {string} [paradigm]
* @property {string} [clientId]
* @property {string} [clientSecret]
* @property {string} [callbackUrl]
* @property {string} [domain1]
* @property {string} [domain2]
* @property {string} [domain3]
*/
/**
* @typedef {object} DbConnectType
* @property {string} url - Remote URL
* @property {string} key - Full Access API key
* @property {DSQL_MYSQL_user_databases_Type} database - DSQL database entry
* @property {DSQL_DatabaseSchemaType} dbSchema - Database JSON schema
* @property {"pull" | "push"} type - Type of connection: "pull" or "push"
* @property {DSQL_DatabaseSchemaType[]} [remoteDbs] - All Databases Pulled from the remote
* @property {DSQL_DatabaseSchemaType} [targetDb] - The Target Database to be cloned
*/
/**
* @typedef {object} MYSQL_MediaType
* @property {number} [id]
* @property {number} [user_id]
* @property {string} [media_name]
* @property {string} [folder]
* @property {string} [media_url]
* @property {string} [media_thumbnail_url]
* @property {string} [media_type]
* @property {string} [width]
* @property {string} [height]
* @property {string} [size]
* @property {string} [private]
*/
/**
* @typedef {object} UserFileObject
* @property {string} [title]
* @property {string} [path]
* @property {string} [data]
*/
/**
* @typedef {object} UserFileObject2
* @property {string} [type]
* @property {string} [name]
* @property {string} [root]
* @property {UserFileObject2[]} [content]
*/
/**
* @typedef {object} MYSQL_user_users_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {number} [user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {number} [invited_user_id] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [database] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [database_access] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [first_name] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [last_name] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [email] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [username] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [password] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [phone] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [user_type] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [user_priviledge] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [image] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [image_thumbnail] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [city] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [state] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [country] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [zip_code] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [address] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [social_login] - NULL=`YES` Key=`` Default=`0` Extra=``
* @property {string} [social_platform] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [social_id] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [verification_status] - NULL=`YES` Key=`` Default=`0` Extra=``
* @property {string} [more_user_data] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED`
* @property {string} [date_updated] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED on update CURRENT_TIMESTAMP`
* @property {string} [inviteeFirstName] - QUERY JOIN
* @property {string} [inviteeLastName] - QUERY JOIN
* @property {string} [inviteeEmail] - QUERY JOIN
* @property {string} [inviteeImage] - QUERY JOIN
*/
/**
* @typedef {object} MYSQL_user_database_tables_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {number} [user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {number} [db_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {string} [db_slug] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [table_name] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [table_slug] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [table_description] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [child_table] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [child_table_parent_database] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [child_table_parent_table] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED`
* @property {string} [date_updated] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED on update CURRENT_TIMESTAMP`
*/
/**
* @typedef {object} MYSQL_user_media_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {number} [user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {string} [media_name] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [folder] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [media_url] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [media_thumbnail_url] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [media_path] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [media_thumbnail_path] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [media_type] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [width] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [height] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [size] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [private] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED`
* @property {string} [date_updated] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED on update CURRENT_TIMESTAMP`
*/
/**
* @typedef {object} MYSQL_delegated_users_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {number} [user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {number} [delegated_user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {string} [permissions] - NULL=`YES` Key=`` Default=`edit` Extra=``
* @property {number} [permission_level_code] - NULL=`YES` Key=`` Default=`1` Extra=``
* @property {string} [date_created] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED`
* @property {string} [date_updated] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED on update CURRENT_TIMESTAMP`
*/
/**
* @typedef {object} MYSQL_invitations_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {number} [inviting_user_id] - NULL=`NO` Key=`MUL` Default=`null` Extra=``
* @property {string} [invited_user_email] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [invitation_status] - NULL=`YES` Key=`` Default=`Pending` Extra=``
* @property {string} [database_access] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [priviledge] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [db_tables_data] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED`
* @property {string} [date_updated] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED on update CURRENT_TIMESTAMP`
*/
/**
* @typedef {object} MYSQL_docs_pages_table_def
* @property {number} [id] - NULL=`NO` Key=`PRI` Default=`null` Extra=`auto_increment`
* @property {string} [title] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [slug] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [description] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [content] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [text_content] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {number} [level] - NULL=`YES` Key=`` Default=`1` Extra=``
* @property {number} [page_order] - NULL=`YES` Key=`` Default=`1` Extra=``
* @property {number} [parent_id] - NULL=`YES` Key=`` Default=`null` Extra=``
* @property {string} [date_created] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_created_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_created_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED`
* @property {string} [date_updated] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {number} [date_updated_code] - NULL=`NO` Key=`` Default=`null` Extra=``
* @property {string} [date_updated_timestamp] - NULL=`YES` Key=`` Default=`CURRENT_TIMESTAMP` Extra=`DEFAULT_GENERATED on update CURRENT_TIMESTAMP`
*/
/**
* @typedef {object} MYSQL_delegated_user_tables_table_def
* @property {number} [id]
* @property {number} [delegated_user_id]
* @property {number} [root_user_id]
* @property {string} [database]
* @property {string} [table]
* @property {string} [priviledge]
* @property {string} [date_created]
* @property {number} [date_created_code]
* @property {string} [date_created_timestamp]
* @property {string} [date_updated]
* @property {number} [date_updated_code]
* @property {string} [date_updated_timestamp]
*/
// React.Dispatch<React.SetStateAction<any>>
// React.MutableRefObject<HTMLElement | undefined>
// React.MutableRefObject<React.Dispatch<React.SetStateAction<number>>>
// React.LegacyRef<HTMLDivElement | undefined>
// /** @type {HTMLFormElement} */ // @ts-ignore
// const formEl = e.target;
// /** @type {HTMLInputElement} */ // @ts-ignore
// const inputEl = e.target;
// /** @type {HTMLSelectElement} */ // @ts-ignore
// const selectEl = e.target;
/** @type {any} */
/** @type {any} */ // @ts-ignore
// @ts-ignore
// @param {object} params
// /** @type {any} */
// const dbTablesState = React.useState(0);
// /** @type {[ state: any, dispatch: React.Dispatch<React.SetStateAction<any>> ]} */ // @ts-ignore
// const [dbTables, setDbTables] = dbTablesState;
// /** @type {import("@/package-shared/types").AddEntryContextType} */ // @ts-ignore
// const init = {};
// export const AddTableEntryContext = React.createContext(init);

View File

@ -0,0 +1,48 @@
// @ts-check
const fs = require("fs");
const path = require("path");
const mysql = require("serverless-mysql");
const SSL_DIR = "/app/ssl";
const MASTER = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_USERNAME,
password: process.env.DSQL_DB_PASSWORD,
database: process.env.DSQL_DB_NAME,
port: process.env.DB_PORT ? Number(process.env.DB_PORT) : undefined,
charset: "utf8mb4",
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
/**
* DSQL user read-only DB handler
* @param {object} params
* @param {string} params.paradigm
* @param {string} params.database
* @param {string} params.queryString
* @param {string[]} [params.queryValues]
*/ // @ts-ignore
async function DB_HANDLER(...args) {
try {
const results = await MASTER.query(...args);
/** ********************* Clean up */
await MASTER.end();
return JSON.parse(JSON.stringify(results));
} catch (/** @type {any} */ error) {
console.log("DB Error =>", error);
return {
success: false,
error: error.message,
};
}
}
module.exports = DB_HANDLER;

View File

@ -0,0 +1,129 @@
// @ts-check
const fs = require("fs");
const path = require("path");
const mysql = require("serverless-mysql");
const SSL_DIR = "/app/ssl";
let DSQL_USER = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_READ_ONLY_USERNAME,
password: process.env.DSQL_DB_READ_ONLY_PASSWORD,
charset: "utf8mb4",
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
/**
* DSQL user read-only DB handler
* @param {object} params
* @param {"Full Access" | "FA" | "Read Only"} params.paradigm
* @param {string} params.database
* @param {string} params.queryString
* @param {string[]} [params.queryValues]
*/
function DSQL_USER_DB_HANDLER({
paradigm,
database,
queryString,
queryValues,
}) {
try {
return new Promise((resolve, reject) => {
const fullAccess = paradigm?.match(/full.access|^fa$/i)
? true
: false;
try {
if (fullAccess) {
DSQL_USER = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_FULL_ACCESS_USERNAME,
password: process.env.DSQL_DB_FULL_ACCESS_PASSWORD,
database: database,
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
} else {
DSQL_USER = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_READ_ONLY_USERNAME,
password: process.env.DSQL_DB_READ_ONLY_PASSWORD,
database: database,
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
}
/**
* ### Run query Function
* @param {any} results
*/
function runQuery(results) {
DSQL_USER.end();
resolve(JSON.parse(JSON.stringify(results)));
}
/**
* ### Query Error
* @param {any} err
*/
function queryError(err) {
DSQL_USER.end();
resolve({
error: err.message,
queryStringGenerated: queryString,
queryValuesGenerated: queryValues,
sql: err.sql,
});
}
if (
queryValues &&
Array.isArray(queryValues) &&
queryValues[0]
) {
DSQL_USER.query(queryString, queryValues)
.then(runQuery)
.catch(queryError);
} else {
DSQL_USER.query(queryString)
.then(runQuery)
.catch(queryError);
}
////////////////////////////////////////
} catch (/** @type {any} */ error) {
////////////////////////////////////////
fs.appendFileSync(
"./.tmp/dbErrorLogs.txt",
error.message + "\n" + Date() + "\n\n\n",
"utf8"
);
resolve({
error: error.message,
});
}
});
} catch (/** @type {any} */ error) {
return {
success: false,
error: error.message,
};
}
}
module.exports = DSQL_USER_DB_HANDLER;

View File

@ -0,0 +1,63 @@
// @ts-check
const fs = require("fs");
const path = require("path");
// const mysql = require("mysql");
// const NO_DB = mysql.createConnection({
// host: process.env.DSQL_DB_HOST,
// user: process.env.DSQL_DB_USERNAME,
// password: process.env.DSQL_DB_PASSWORD,
// charset: "utf8mb4",
// });
const mysql = require("serverless-mysql");
const SSL_DIR = "/app/ssl";
let NO_DB = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_USERNAME,
password: process.env.DSQL_DB_PASSWORD,
charset: "utf8mb4",
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
/**
* DSQL user read-only DB handler
* @param {object} params
* @param {string} params.paradigm
* @param {string} params.database
* @param {string} params.queryString
* @param {string[]} [params.queryValues]
*/ // @ts-ignore
function NO_DB_HANDLER(...args) {
try {
return new Promise((resolve, reject) => {
NO_DB.query(...args)
.then((results) => {
NO_DB.end();
resolve(JSON.parse(JSON.stringify(results)));
})
.catch((err) => {
NO_DB.end();
resolve({
error: err.message,
sql: err.sql,
});
});
});
} catch (/** @type {any} */ error) {
return {
success: false,
error: error.message,
};
}
}
module.exports = NO_DB_HANDLER;

View File

@ -0,0 +1,54 @@
// @ts-check
const fs = require("fs");
const path = require("path");
const mysql = require("serverless-mysql");
const SSL_DIR = "/app/ssl";
let NO_DB = mysql({
config: {
host: process.env.DSQL_DB_HOST,
user: process.env.DSQL_DB_USERNAME,
password: process.env.DSQL_DB_PASSWORD,
charset: "utf8mb4",
ssl: {
ca: fs.readFileSync(`${SSL_DIR}/ca-cert.pem`),
},
},
});
/**
* DSQL user read-only DB handler
* @param {object} params
* @param {string} params.paradigm
* @param {string} params.database
* @param {string} params.queryString
* @param {string[]} [params.queryValues]
*/ // @ts-ignore
function ROOT_DB_HANDLER(...args) {
try {
return new Promise((resolve, reject) => {
NO_DB.query(...args)
.then((results) => {
NO_DB.end();
resolve(JSON.parse(JSON.stringify(results)));
})
.catch((err) => {
NO_DB.end();
resolve({
error: err.message,
sql: err.sql,
});
});
});
} catch (/** @type {any} */ error) {
return {
success: false,
error: error.message,
};
}
}
module.exports = ROOT_DB_HANDLER;

View File

@ -0,0 +1,49 @@
// @ts-check
const fs = require("fs");
const DSQL_USER_DB_HANDLER = require("./DSQL_USER_DB_HANDLER");
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
process.addListener("exit", async (code) => {
console.log("PROCESS EXITING ...");
});
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Global function
* ================================================
* @description this sets all require global variables. This only runs once.
*/
module.exports = function globalFunction() {
/**
* Main Db Handler
*/
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* Main Db Handler
*/
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
/**
* DSQL user read-only DB handler
* @param {object} params
* @param {string} params.paradigm
* @param {string} params.database
* @param {string} params.queryString
* @param {string[]} [params.queryValues]
*/
DSQL_USER_DB_HANDLER;
};

View File

@ -0,0 +1,38 @@
/**
*
* @param {string | null | number} string
* @param {(this: any, key: string, value: any) => any} [reviver]
* @returns {{ [key: string]: any } | { [key: string]: any }[] | undefined}
*/
function parse(string, reviver) {
if (!string) return undefined;
if (typeof string == "object") return string;
if (typeof string !== "string") return undefined;
try {
return JSON.parse(string, reviver);
} catch (error) {
return undefined;
}
}
/**
*
* @param {any} value
* @param {(this: any, key: string, value: any) => any} [replacer]
* @param { string | number } [space]
* @returns {string | undefined}
*/
function stringify(value, replacer, space) {
try {
return JSON.stringify(value, replacer, space);
} catch (error) {
return undefined;
}
}
const EJSON = {
parse,
stringify,
};
module.exports = EJSON;

View File

@ -1,6 +1,6 @@
{ {
"name": "datasquirel", "name": "datasquirel",
"version": "2.3.4", "version": "2.3.5",
"description": "Cloud-based SQL data management tool", "description": "Cloud-based SQL data management tool",
"main": "index.js", "main": "index.js",
"bin": { "bin": {
@ -26,11 +26,19 @@
}, },
"homepage": "https://datasquirel.com/", "homepage": "https://datasquirel.com/",
"dependencies": { "dependencies": {
"@types/ace": "^0.0.52",
"@types/react": "^18.3.12",
"@types/tinymce": "^4.6.9",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"generate-password": "^1.7.1",
"lodash": "^4.17.21",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"nodemailer": "^6.9.14" "nodemailer": "^6.9.14",
"sanitize-html": "^2.13.1",
"serverless-mysql": "^1.5.5"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.17.13",
"@types/mysql": "^2.15.21", "@types/mysql": "^2.15.21",
"@types/node": "^22.7.5" "@types/node": "^22.7.5"
} }

View File

@ -29,7 +29,7 @@
"types", "types",
"users", "users",
"utils", "utils",
"package-shared/types" "package-shared"
], ],
"exclude": ["node_modules", "dump"] "exclude": ["node_modules", "dump"]
} }

View File

@ -27,7 +27,7 @@ const localUpdateUser = require("../engine/user/update-user");
* @param {object} params - API Key * @param {object} params - API Key
* @param {String} params.key - API Key * @param {String} params.key - API Key
* @param {String} params.database - Target Database * @param {String} params.database - Target Database
* @param {{ id: number } & Object.<string, *>} params.payload - User Object: ID is required * @param {{ id: number } & Object.<string, any>} params.payload - User Object: ID is required
* *
* @returns { Promise<import("../package-shared/types").UpdateUserFunctionReturn>} * @returns { Promise<import("../package-shared/types").UpdateUserFunctionReturn>}
*/ */

View File

@ -44,19 +44,16 @@ async function get({ key, db, query, queryValues, tableName }) {
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { const {
DSQL_HOST, DSQL_DB_HOST,
DSQL_USER, DSQL_DB_USERNAME,
DSQL_PASS, DSQL_MARIADB_ROOT_PASSWORD,
DSQL_DB_NAME, DSQL_DB_NAME,
DSQL_KEY,
DSQL_REF_DB_NAME,
DSQL_FULL_SYNC,
} = process.env; } = process.env;
if ( if (
DSQL_HOST?.match(/./) && DSQL_DB_HOST?.match(/./) &&
DSQL_USER?.match(/./) && DSQL_DB_USERNAME?.match(/./) &&
DSQL_PASS?.match(/./) && DSQL_MARIADB_ROOT_PASSWORD?.match(/./) &&
DSQL_DB_NAME?.match(/./) DSQL_DB_NAME?.match(/./)
) { ) {
/** @type {import("../package-shared/types").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../package-shared/types").DSQL_DatabaseSchemaType | undefined} */