Updates
This commit is contained in:
parent
d81f38809b
commit
190598aa3f
@ -3,9 +3,9 @@
|
||||
* No imports found for this Module
|
||||
==== MODULE TRACE END ==== */
|
||||
|
||||
// @ts-check
|
||||
const runQuery = require("../../package-shared/functions/backend/db/runQuery");
|
||||
|
||||
const runQuery = require("./utils/runQuery");
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @typedef {Object} LocalGetReturn
|
||||
@ -39,7 +39,6 @@ async function localGet({ options, dbSchema }) {
|
||||
|
||||
/** @type {string | undefined | any } */
|
||||
const tableName = options?.tableName ? options.tableName : undefined;
|
||||
|
||||
const dbFullName = process.env.DSQL_DB_NAME || "";
|
||||
|
||||
/**
|
||||
@ -71,6 +70,7 @@ async function localGet({ options, dbSchema }) {
|
||||
queryValuesArray: queryValues,
|
||||
dbSchema,
|
||||
tableName,
|
||||
local: true,
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
const runQuery = require("./utils/runQuery");
|
||||
const runQuery = require("../../package-shared/functions/backend/db/runQuery");
|
||||
|
||||
/**
|
||||
* Make a get request to Datasquirel API
|
||||
@ -52,6 +52,7 @@ async function localPost({ options, dbSchema }) {
|
||||
dbSchema: dbSchema,
|
||||
queryValuesArray: queryValues,
|
||||
tableName,
|
||||
local: true,
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
|
@ -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;
|
@ -1,10 +1,9 @@
|
||||
// @ts-check
|
||||
|
||||
const hashPassword = require("../../functions/hashPassword");
|
||||
const addDbEntry = require("../../package-shared/functions/backend/db/addDbEntry");
|
||||
const addUsersTableToDb = require("../engine/addUsersTableToDb");
|
||||
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
|
||||
|
@ -8,8 +8,8 @@
|
||||
const fs = require("fs");
|
||||
const http = require("http");
|
||||
const varDatabaseDbHandler = require("../../../engine/utils/varDatabaseDbHandler");
|
||||
const addDbEntry = require("../../../query/utils/addDbEntry");
|
||||
const encrypt = require("../../../../functions/encrypt");
|
||||
const addDbEntry = require("../../../../package-shared/functions/backend/db/addDbEntry");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
const updateDbEntry = require("../query/utils/updateDbEntry");
|
||||
const updateDbEntry = require("../../package-shared/functions/backend/db/updateDbEntry");
|
||||
|
||||
/**
|
||||
* @typedef {Object} LocalPostReturn
|
||||
|
300
package-lock.json
generated
300
package-lock.json
generated
@ -1,32 +1,62 @@
|
||||
{
|
||||
"name": "datasquirel",
|
||||
"version": "2.1.1",
|
||||
"version": "2.3.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "datasquirel",
|
||||
"version": "2.1.1",
|
||||
"version": "2.3.5",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/ace": "^0.0.52",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/tinymce": "^4.6.9",
|
||||
"dotenv": "^16.3.1",
|
||||
"generate-password": "^1.7.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mysql": "^2.18.1",
|
||||
"nodemailer": "^6.9.14"
|
||||
"nodemailer": "^6.9.14",
|
||||
"sanitize-html": "^2.13.1",
|
||||
"serverless-mysql": "^1.5.5"
|
||||
},
|
||||
"bin": {
|
||||
"dsql-dump": "engine/dump.js",
|
||||
"dsql-watch": "engine/dsql.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/mysql": "^2.15.21",
|
||||
"@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": {
|
||||
"version": "2.15.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.21.tgz",
|
||||
"integrity": "sha512-NPotx5CVful7yB+qZbWtXL2fA4e7aEHkihHLjklc6ID8aq7bhguHgeIoC1EmSNTAuCgI6ZXrjt2ZSaXnYX0EUg==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
@ -35,12 +65,43 @@
|
||||
"version": "22.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
|
||||
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"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": {
|
||||
"version": "9.0.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "16.3.1",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
|
||||
@ -65,16 +196,80 @@
|
||||
"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": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"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": {
|
||||
"version": "2.18.1",
|
||||
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
|
||||
@ -89,6 +284,24 @@
|
||||
"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": {
|
||||
"version": "6.9.14",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz",
|
||||
@ -98,6 +311,46 @@
|
||||
"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": {
|
||||
"version": "2.0.1",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
|
||||
@ -142,7 +430,7 @@
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
|
@ -1,3 +1,7 @@
|
||||
# Shared resources
|
||||
|
||||
This directory contains data (mostly type definitions) shared by both the datasquirel NPM package and the datasquirel web app
|
||||
|
||||
## Functions
|
||||
|
||||
## Types
|
||||
|
66
package-shared/functions/backend/addMariadbUser.js
Normal file
66
package-shared/functions/backend/addMariadbUser.js
Normal 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
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////
|
43
package-shared/functions/backend/api-cred.js
Normal file
43
package-shared/functions/backend/api-cred.js
Normal 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;
|
163
package-shared/functions/backend/db/add.js
Normal file
163
package-shared/functions/backend/db/add.js
Normal 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;
|
||||
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
};
|
232
package-shared/functions/backend/db/addDbEntry.js
Normal file
232
package-shared/functions/backend/db/addDbEntry.js
Normal 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;
|
@ -1,6 +1,7 @@
|
||||
// @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
|
||||
@ -19,7 +20,7 @@ const dbHandler = require("../../engine/utils/dbHandler");
|
||||
* "Read only" or "Full Access"? Defaults to "Read Only"
|
||||
* @param {string} params.dbFullName - Database full 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|number} params.identifierValue - Update row identifier column value
|
||||
*
|
||||
@ -37,6 +38,14 @@ async function deleteDbEntry({
|
||||
/**
|
||||
* 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,10 +58,13 @@ async function deleteDbEntry({
|
||||
*/
|
||||
const query = `DELETE FROM ${tableName} WHERE \`${identifierColumnName}\`=?`;
|
||||
|
||||
const deletedEntry = await dbHandler({
|
||||
query: query,
|
||||
const deletedEntry = isMaster
|
||||
? await dbHandler(query, [identifierValue])
|
||||
: await dbHandler({
|
||||
paradigm,
|
||||
queryString: query,
|
||||
database: dbFullName,
|
||||
values: [identifierValue],
|
||||
queryValues: [identifierValue],
|
||||
});
|
||||
|
||||
////////////////////////////////////////
|
41
package-shared/functions/backend/db/pathTraversalCheck.js
Normal file
41
package-shared/functions/backend/db/pathTraversalCheck.js
Normal 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;
|
@ -1,21 +1,25 @@
|
||||
/** # 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)
|
||||
* `require` Statement Found in [post.js](d:\GitHub\dsql\engine\query\post.js)
|
||||
* `require` Statement Found in [add-user.js](d:\GitHub\dsql\engine\user\add-user.js)
|
||||
* `require` Statement Found in [update-user.js](d:\GitHub\dsql\engine\user\update-user.js)
|
||||
* `import` Statement Found in [get.js] => file:///d:\GitHub\datasquirel\pages\api\query\get.js
|
||||
* `import` Statement Found in [post.js] => file:///d:\GitHub\datasquirel\pages\api\query\post.js
|
||||
* `import` Statement Found in [add-user.js] => file:///d:\GitHub\datasquirel\pages\api\user\add-user.js
|
||||
==== MODULE TRACE END ==== */
|
||||
|
||||
// @ts-check
|
||||
|
||||
const fs = require("fs");
|
||||
|
||||
const fullAccessDbHandler = require("../fullAccessDbHandler");
|
||||
const varReadOnlyDatabaseDbHandler = require("../varReadOnlyDatabaseDbHandler");
|
||||
const serverError = require("../serverError");
|
||||
|
||||
const addDbEntry = require("./addDbEntry");
|
||||
const updateDbEntry = require("./updateDbEntry");
|
||||
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 {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 {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.tableName] - Table Name
|
||||
*
|
||||
* @return {Promise<{result: *, error?: *}>}
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
async function runQuery({
|
||||
dbFullName,
|
||||
@ -44,16 +49,20 @@ async function runQuery({
|
||||
dbSchema,
|
||||
queryValuesArray,
|
||||
tableName,
|
||||
local,
|
||||
}) {
|
||||
/**
|
||||
* Declare variables
|
||||
*
|
||||
* @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) {
|
||||
try {
|
||||
@ -68,7 +77,9 @@ async function runQuery({
|
||||
tableSchema = dbSchema.tables.filter(
|
||||
(tb) => tb?.tableName === table
|
||||
)[0];
|
||||
} catch (_err) {}
|
||||
} catch (_err) {
|
||||
// console.log("ERROR getting tableSchema: ", _err.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,12 +89,29 @@ async function runQuery({
|
||||
*/
|
||||
try {
|
||||
if (typeof query === "string") {
|
||||
result = await varDatabaseDbHandler({
|
||||
if (local) {
|
||||
const rawResults = await DB_HANDLER(query, queryValuesArray);
|
||||
result = tableSchema
|
||||
? parseDbResults({
|
||||
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") {
|
||||
/**
|
||||
* Declare variables
|
||||
@ -104,6 +132,8 @@ async function runQuery({
|
||||
switch (action.toLowerCase()) {
|
||||
case "insert":
|
||||
result = await addDbEntry({
|
||||
dbContext: local ? "Master" : "Dsql User",
|
||||
paradigm: "Full Access",
|
||||
dbFullName: dbFullName,
|
||||
tableName: table,
|
||||
data: data,
|
||||
@ -111,8 +141,6 @@ async function runQuery({
|
||||
duplicateColumnName,
|
||||
duplicateColumnValue,
|
||||
tableSchema,
|
||||
encryptionKey,
|
||||
encryptionSalt,
|
||||
});
|
||||
|
||||
if (!result?.insertId) {
|
||||
@ -123,7 +151,7 @@ async function runQuery({
|
||||
|
||||
case "update":
|
||||
result = await updateDbEntry({
|
||||
dbContext: "Dsql User",
|
||||
dbContext: local ? "Master" : "Dsql User",
|
||||
paradigm: "Full Access",
|
||||
dbFullName: dbFullName,
|
||||
tableName: table,
|
||||
@ -131,15 +159,13 @@ async function runQuery({
|
||||
identifierColumnName,
|
||||
identifierValue,
|
||||
tableSchema,
|
||||
encryptionKey,
|
||||
encryptionSalt,
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case "delete":
|
||||
result = await deleteDbEntry({
|
||||
dbContext: "Dsql User",
|
||||
dbContext: local ? "Master" : "Dsql User",
|
||||
paradigm: "Full Access",
|
||||
dbFullName: dbFullName,
|
||||
tableName: table,
|
||||
@ -151,12 +177,7 @@ async function runQuery({
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log("Unhandled Query");
|
||||
console.log("Query Recieved =>", query);
|
||||
result = {
|
||||
result: null,
|
||||
error: "Unhandled Query",
|
||||
};
|
||||
result = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -164,14 +185,12 @@ async function runQuery({
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
} catch (/** @type {*} */ error) {
|
||||
console.log("Error in Running Query =>", error.message);
|
||||
console.log("Query Recieved =>", query);
|
||||
|
||||
result = {
|
||||
result: null,
|
||||
error: "Error in running Query => " + error.message,
|
||||
};
|
||||
} catch (/** @type {any} */ error) {
|
||||
serverError({
|
||||
component: "functions/backend/runQuery",
|
||||
message: error.message,
|
||||
});
|
||||
result = null;
|
||||
error = error.message;
|
||||
}
|
||||
|
207
package-shared/functions/backend/db/sanitizeSql.js
Normal file
207
package-shared/functions/backend/db/sanitizeSql.js
Normal 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;
|
@ -1,11 +1,13 @@
|
||||
// @ts-check
|
||||
|
||||
const encrypt = require("../../../functions/encrypt");
|
||||
const dbHandler = require("../../engine/utils/dbHandler");
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -18,14 +20,14 @@ const dbHandler = require("../../engine/utils/dbHandler");
|
||||
* 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.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.encryptionKey]
|
||||
* @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 | number} params.identifierValue - Update row identifier column value
|
||||
* @param {string} params.encryptionKey - Encryption key
|
||||
* @param {string} params.encryptionSalt - Encryption salt
|
||||
*
|
||||
* @returns {Promise<object|null>}
|
||||
*/
|
||||
@ -46,6 +48,15 @@ async function updateDbEntry({
|
||||
*/
|
||||
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 updateValues = [];
|
||||
|
||||
/**
|
||||
* Declare variables
|
||||
*
|
||||
* @description Declare "results" variable
|
||||
*/
|
||||
for (let i = 0; i < dataKeys.length; i++) {
|
||||
try {
|
||||
const dataKey = dataKeys[i];
|
||||
// @ts-ignore
|
||||
let value = data[dataKey];
|
||||
|
||||
const targetFieldSchemaArray = tableSchema
|
||||
@ -80,22 +87,31 @@ async function updateDbEntry({
|
||||
? targetFieldSchemaArray[0]
|
||||
: null;
|
||||
|
||||
if (typeof value == "undefined") continue;
|
||||
if (
|
||||
typeof value !== "string" &&
|
||||
typeof value !== "number" &&
|
||||
!value
|
||||
)
|
||||
continue;
|
||||
if (value == null || value == undefined) continue;
|
||||
|
||||
if (targetFieldSchema?.richText) {
|
||||
value = sanitizeHtml(value, sanitizeHtmlOptions);
|
||||
}
|
||||
|
||||
if (targetFieldSchema?.encrypted) {
|
||||
value = encrypt({ data: value, encryptionKey, encryptionSalt });
|
||||
value = encrypt(value, encryptionKey, encryptionSalt);
|
||||
}
|
||||
|
||||
if (typeof value === "object") {
|
||||
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)) {
|
||||
value = {
|
||||
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)) {
|
||||
value = {
|
||||
toSqlString: function () {
|
||||
@ -123,14 +128,17 @@ async function updateDbEntry({
|
||||
};
|
||||
}
|
||||
|
||||
if (!value && typeof value == "number" && value != 0) continue;
|
||||
|
||||
updateKeyValueArray.push(`\`${dataKey}\`=?`);
|
||||
|
||||
if (typeof value == "number") {
|
||||
updateValues.push(String(value));
|
||||
} else {
|
||||
updateValues.push(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
} catch (/** @type {*} */ error) {
|
||||
} catch (/** @type {any} */ error) {
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
|
||||
@ -157,10 +165,13 @@ async function updateDbEntry({
|
||||
|
||||
updateValues.push(identifierValue);
|
||||
|
||||
const updatedEntry = await dbHandler({
|
||||
const updatedEntry = isMaster
|
||||
? await dbHandler(query, updateValues)
|
||||
: await dbHandler({
|
||||
paradigm,
|
||||
database: dbFullName,
|
||||
query: query,
|
||||
values: updateValues,
|
||||
queryString: query,
|
||||
queryValues: updateValues,
|
||||
});
|
||||
|
||||
////////////////////////////////////////
|
90
package-shared/functions/backend/dbHandler.js
Normal file
90
package-shared/functions/backend/dbHandler.js
Normal 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;
|
||||
}
|
||||
};
|
29
package-shared/functions/backend/decrypt.js
Normal file
29
package-shared/functions/backend/decrypt.js
Normal 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;
|
15
package-shared/functions/backend/defaultFieldsRegexp.js
Normal file
15
package-shared/functions/backend/defaultFieldsRegexp.js
Normal 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;
|
43
package-shared/functions/backend/encrypt.js
Normal file
43
package-shared/functions/backend/encrypt.js
Normal 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;
|
78
package-shared/functions/backend/fullAccessDbHandler.js
Normal file
78
package-shared/functions/backend/fullAccessDbHandler.js
Normal 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;
|
||||
}
|
||||
};
|
12
package-shared/functions/backend/html/sanitizeHtmlOptions.js
Normal file
12
package-shared/functions/backend/html/sanitizeHtmlOptions.js
Normal 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;
|
59
package-shared/functions/backend/noDatabaseDbHandler.js
Normal file
59
package-shared/functions/backend/noDatabaseDbHandler.js
Normal 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;
|
||||
}
|
||||
};
|
76
package-shared/functions/backend/parseDbResults.js
Normal file
76
package-shared/functions/backend/parseDbResults.js
Normal 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;
|
||||
}
|
||||
};
|
31
package-shared/functions/backend/passwordHash.js
Normal file
31
package-shared/functions/backend/passwordHash.js
Normal 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;
|
||||
// };
|
55
package-shared/functions/backend/serverError.js
Normal file
55
package-shared/functions/backend/serverError.js
Normal 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}`);
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
38
package-shared/functions/backend/suSocketAuth.js
Normal file
38
package-shared/functions/backend/suSocketAuth.js
Normal 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;
|
||||
};
|
116
package-shared/functions/backend/varDatabaseDbHandler.js
Normal file
116
package-shared/functions/backend/varDatabaseDbHandler.js
Normal 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;
|
||||
}
|
||||
};
|
@ -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;
|
||||
}
|
||||
};
|
726
package-shared/types/index.d.ts
vendored
726
package-shared/types/index.d.ts
vendored
@ -1,5 +1,6 @@
|
||||
import http from "http";
|
||||
|
||||
import { Editor } from "tinymce";
|
||||
export type DSQL_DatabaseFullName = string;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -139,6 +140,7 @@ export interface DSQL_MYSQL_FOREIGN_KEYS_Type {
|
||||
////////////////////////////////////////
|
||||
|
||||
export interface DSQL_MYSQL_user_databases_Type {
|
||||
id: number;
|
||||
user_id: number;
|
||||
db_full_name: string;
|
||||
db_name: string;
|
||||
@ -147,6 +149,17 @@ export interface DSQL_MYSQL_user_databases_Type {
|
||||
db_description: string;
|
||||
active_clone: number;
|
||||
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 {
|
||||
@ -370,3 +383,716 @@ export interface PostInsertReturn {
|
||||
protocol41: boolean;
|
||||
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;
|
||||
};
|
||||
|
@ -153,6 +153,7 @@
|
||||
|
||||
/**
|
||||
* @typedef {object} DSQL_MYSQL_user_databases_Type
|
||||
* @property {number} id
|
||||
* @property {number} user_id - User Id
|
||||
* @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)
|
||||
@ -161,6 +162,15 @@
|
||||
* @property {string} db_description - Database description
|
||||
* @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 {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 {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);
|
||||
|
48
package-shared/utils/backend/global-db/DB_HANDLER.js
Normal file
48
package-shared/utils/backend/global-db/DB_HANDLER.js
Normal 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;
|
129
package-shared/utils/backend/global-db/DSQL_USER_DB_HANDLER.js
Normal file
129
package-shared/utils/backend/global-db/DSQL_USER_DB_HANDLER.js
Normal 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;
|
63
package-shared/utils/backend/global-db/NO_DB_HANDLER.js
Normal file
63
package-shared/utils/backend/global-db/NO_DB_HANDLER.js
Normal 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;
|
54
package-shared/utils/backend/global-db/ROOT_DB_HANDLER.js
Normal file
54
package-shared/utils/backend/global-db/ROOT_DB_HANDLER.js
Normal 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;
|
49
package-shared/utils/backend/global-db/index.js
Normal file
49
package-shared/utils/backend/global-db/index.js
Normal 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;
|
||||
};
|
38
package-shared/utils/ejson.js
Normal file
38
package-shared/utils/ejson.js
Normal 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;
|
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "datasquirel",
|
||||
"version": "2.3.4",
|
||||
"version": "2.3.5",
|
||||
"description": "Cloud-based SQL data management tool",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
@ -26,11 +26,19 @@
|
||||
},
|
||||
"homepage": "https://datasquirel.com/",
|
||||
"dependencies": {
|
||||
"@types/ace": "^0.0.52",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/tinymce": "^4.6.9",
|
||||
"dotenv": "^16.3.1",
|
||||
"generate-password": "^1.7.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mysql": "^2.18.1",
|
||||
"nodemailer": "^6.9.14"
|
||||
"nodemailer": "^6.9.14",
|
||||
"sanitize-html": "^2.13.1",
|
||||
"serverless-mysql": "^1.5.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/mysql": "^2.15.21",
|
||||
"@types/node": "^22.7.5"
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
"types",
|
||||
"users",
|
||||
"utils",
|
||||
"package-shared/types"
|
||||
"package-shared"
|
||||
],
|
||||
"exclude": ["node_modules", "dump"]
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ const localUpdateUser = require("../engine/user/update-user");
|
||||
* @param {object} params - API Key
|
||||
* @param {String} params.key - API Key
|
||||
* @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>}
|
||||
*/
|
||||
|
15
utils/get.js
15
utils/get.js
@ -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
|
||||
*/
|
||||
const {
|
||||
DSQL_HOST,
|
||||
DSQL_USER,
|
||||
DSQL_PASS,
|
||||
DSQL_DB_HOST,
|
||||
DSQL_DB_USERNAME,
|
||||
DSQL_MARIADB_ROOT_PASSWORD,
|
||||
DSQL_DB_NAME,
|
||||
DSQL_KEY,
|
||||
DSQL_REF_DB_NAME,
|
||||
DSQL_FULL_SYNC,
|
||||
} = process.env;
|
||||
|
||||
if (
|
||||
DSQL_HOST?.match(/./) &&
|
||||
DSQL_USER?.match(/./) &&
|
||||
DSQL_PASS?.match(/./) &&
|
||||
DSQL_DB_HOST?.match(/./) &&
|
||||
DSQL_DB_USERNAME?.match(/./) &&
|
||||
DSQL_MARIADB_ROOT_PASSWORD?.match(/./) &&
|
||||
DSQL_DB_NAME?.match(/./)
|
||||
) {
|
||||
/** @type {import("../package-shared/types").DSQL_DatabaseSchemaType | undefined} */
|
||||
|
Loading…
Reference in New Issue
Block a user