This commit is contained in:
Benjamin Toby 2023-09-21 15:00:04 +01:00
parent 70ee0a2c0a
commit 44b013147e
77 changed files with 8511 additions and 8495 deletions

276
.gitignore vendored
View File

@ -1,139 +1,139 @@
# Logs # Logs
logs logs
*.log *.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
lerna-debug.log* lerna-debug.log*
.pnpm-debug.log* .pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html) # Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data # Runtime data
pids pids
*.pid *.pid
*.seed *.seed
*.pid.lock *.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover # Directory for instrumented libs generated by jscoverage/JSCover
lib-cov lib-cov
# Coverage directory used by tools like istanbul # Coverage directory used by tools like istanbul
coverage coverage
*.lcov *.lcov
# nyc test coverage # nyc test coverage
.nyc_output .nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt .grunt
# Bower dependency directory (https://bower.io/) # Bower dependency directory (https://bower.io/)
bower_components bower_components
# node-waf configuration # node-waf configuration
.lock-wscript .lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html) # Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release build/Release
# Dependency directories # Dependency directories
node_modules/ node_modules/
jspm_packages/ jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/) # Snowpack dependency directory (https://snowpack.dev/)
web_modules/ web_modules/
# TypeScript cache # TypeScript cache
*.tsbuildinfo *.tsbuildinfo
# Optional npm cache directory # Optional npm cache directory
.npm .npm
# Optional eslint cache # Optional eslint cache
.eslintcache .eslintcache
# Optional stylelint cache # Optional stylelint cache
.stylelintcache .stylelintcache
# Microbundle cache # Microbundle cache
.rpt2_cache/ .rpt2_cache/
.rts2_cache_cjs/ .rts2_cache_cjs/
.rts2_cache_es/ .rts2_cache_es/
.rts2_cache_umd/ .rts2_cache_umd/
# Optional REPL history # Optional REPL history
.node_repl_history .node_repl_history
# Output of 'npm pack' # Output of 'npm pack'
*.tgz *.tgz
# Yarn Integrity file # Yarn Integrity file
.yarn-integrity .yarn-integrity
# dotenv environment variable files # dotenv environment variable files
*.env *.env
.env .env
.env.development.local .env.development.local
.env.test.local .env.test.local
.env.production.local .env.production.local
.env.local .env.local
# parcel-bundler cache (https://parceljs.org/) # parcel-bundler cache (https://parceljs.org/)
.cache .cache
.parcel-cache .parcel-cache
# Next.js build output # Next.js build output
.next .next
out out
# Nuxt.js build / generate output # Nuxt.js build / generate output
.nuxt .nuxt
dist dist
# Gatsby files # Gatsby files
.cache/ .cache/
# Comment in the public line in if your project uses Gatsby and not Next.js # Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support # https://nextjs.org/blog/next-9-1#public-directory-support
# public # public
# vuepress build output # vuepress build output
.vuepress/dist .vuepress/dist
# vuepress v2.x temp and cache directory # vuepress v2.x temp and cache directory
.temp .temp
.cache .cache
# Docusaurus cache and generated files # Docusaurus cache and generated files
.docusaurus .docusaurus
# Serverless directories # Serverless directories
.serverless/ .serverless/
# FuseBox cache # FuseBox cache
.fusebox/ .fusebox/
# DynamoDB Local files # DynamoDB Local files
.dynamodb/ .dynamodb/
# TernJS port file # TernJS port file
.tern-port .tern-port
# Stores VSCode versions used for testing VSCode extensions # Stores VSCode versions used for testing VSCode extensions
.vscode-test .vscode-test
# yarn v2 # yarn v2
.yarn/cache .yarn/cache
.yarn/unplugged .yarn/unplugged
.yarn/build-state.yml .yarn/build-state.yml
.yarn/install-state.gz .yarn/install-state.gz
.pnp.* .pnp.*
# typescript # typescript
tsconfig.json tsconfig.json
# others # others
deprecated deprecated
.tmp .tmp
test/ test/

236
README.md
View File

@ -1,118 +1,118 @@
# Datasquirel # Datasquirel
This package requires an account with datasquirel, so be sure to create an account at [datasquirel-create-account](https://datasquirel.com/create-account) before you continue. This package requires an account with datasquirel, so be sure to create an account at [datasquirel-create-account](https://datasquirel.com/create-account) before you continue.
## Instalation ## Instalation
```bash ```bash
$ npm install datasquirel $ npm install datasquirel
``` ```
Once the package is installed, you can import the library using `require` approach: Once the package is installed, you can import the library using `require` approach:
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
``` ```
## Usage ## Usage
### Fetch Data ### Fetch Data
This method requires a readonly key or fullaccess API key gotten from [datasquirel](https://datasquirel.com/). It uses a basic https get request paired with some query params. This method requires a readonly key or fullaccess API key gotten from [datasquirel](https://datasquirel.com/). It uses a basic https get request paired with some query params.
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
const getData = await datasquirel.get({ const getData = await datasquirel.get({
key: "aldhkf89asdflksdafh908asdfjkhasdf", // Readonly API Key key: "aldhkf89asdflksdafh908asdfjkhasdf", // Readonly API Key
db: "my_database", // Database name slug (Eg. Db Name => My Database, Db Slug => my_database) db: "my_database", // Database name slug (Eg. Db Name => My Database, Db Slug => my_database)
query: "SELECT * FROM blog_posts", // SQL Query query: "SELECT * FROM blog_posts", // SQL Query
}); });
``` ```
Datasquirel uses all conventional SQL query commands. However you can only use the `SELECT` command when using a readonly API key. Datasquirel uses all conventional SQL query commands. However you can only use the `SELECT` command when using a readonly API key.
### Post Data ### Post Data
This method requires a fullaccess API key gotten from [datasquirel](https://datasquirel.com/). You can perform a basic fetch with this method, as well as more complex operations like `UPDATE`, `DELETE` and `INSERT`. This method requires a fullaccess API key gotten from [datasquirel](https://datasquirel.com/). You can perform a basic fetch with this method, as well as more complex operations like `UPDATE`, `DELETE` and `INSERT`.
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
const postData = await datasquirel.post({ const postData = await datasquirel.post({
key: "aldhkf89asdflksdafh908asdfjkhasdf", // Fullaccess API Key key: "aldhkf89asdflksdafh908asdfjkhasdf", // Fullaccess API Key
payload: { payload: {
action: "insert", // OR "update" OR "delete" OR "select" action: "insert", // OR "update" OR "delete" OR "select"
data: { data: {
user_id: "19aisdn123", user_id: "19aisdn123",
user_first_name: "John", user_first_name: "John",
user_last_name: "Doe", user_last_name: "Doe",
}, },
table: "users", table: "users",
}, },
}); });
``` ```
You can simply replace the `payload` object with an SQL string and it does everything you provide in the SQL command. You can simply replace the `payload` object with an SQL string and it does everything you provide in the SQL command.
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
const postData = await datasquirel.post({ const postData = await datasquirel.post({
key: process.env.FULL_ACCESS_API_KEY, key: process.env.FULL_ACCESS_API_KEY,
payload: "SELECT * FROM blog_posts WHERE user_id='as09d7nasd90'", payload: "SELECT * FROM blog_posts WHERE user_id='as09d7nasd90'",
}); });
``` ```
You can add a condition to the `payload` object to filter the results You can add a condition to the `payload` object to filter the results
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
const postData = await datasquirel.post({ const postData = await datasquirel.post({
key: process.env.FULL_ACCESS_API_KEY, key: process.env.FULL_ACCESS_API_KEY,
payload: { payload: {
action: "delete", action: "delete",
condition: `WHERE user_id='21adwei9jewr' AND type='buyers'`, condition: `WHERE user_id='21adwei9jewr' AND type='buyers'`,
table: "users", table: "users",
}, },
}); });
``` ```
You can use `identifierColumnName` and `identifierValue` when updating an entry. You can use `identifierColumnName` and `identifierValue` when updating an entry.
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
const postData = await datasquirel.post({ const postData = await datasquirel.post({
key: process.env.FULL_ACCESS_API_KEY, key: process.env.FULL_ACCESS_API_KEY,
payload: { payload: {
action: "update", action: "update",
table: "users", table: "users",
identifierColumnName: "id", identifierColumnName: "id",
identifierValue: "21adwei9jewr", identifierValue: "21adwei9jewr",
data: { data: {
first_name: "Mary", first_name: "Mary",
last_name: "Spencer", last_name: "Spencer",
}, },
}, },
}); });
``` ```
### Upload Image ### Upload Image
This method requires is similar to the `post` method, but with different parameters. This method requires is similar to the `post` method, but with different parameters.
```js ```js
const datasquirel = require("datasquirel"); const datasquirel = require("datasquirel");
const postData = await datasquirel.uploadImage({ const postData = await datasquirel.uploadImage({
key: process.env.FULL_ACCESS_API_KEY, key: process.env.FULL_ACCESS_API_KEY,
payload: { payload: {
imageData: "6ejsiua2i29ndsajkfn9n==", // Image in base64 imageData: "6ejsiua2i29ndsajkfn9n==", // Image in base64
imageName: `awesome-waterfalls`, imageName: `awesome-waterfalls`,
mimeType: "jpg", // optional mimeType: "jpg", // optional
thumbnailSize: 120, // optional === This measurement is in pixels(px) thumbnailSize: 120, // optional === This measurement is in pixels(px)
}, },
}); });
``` ```

View File

@ -1,36 +1,36 @@
// @ts-check // @ts-check
/** /**
* Login with Github Function * Login with Github Function
* =============================================================================== * ===============================================================================
* @description This function uses github api to login a user with datasquirel * @description This function uses github api to login a user with datasquirel
* *
* @async * @async
* *
* @param {object} params - Single object passed * @param {object} params - Single object passed
* @param {string} params.clientId - Github app client ID: {@link https://datasquirel.com/docs} * @param {string} params.clientId - Github app client ID: {@link https://datasquirel.com/docs}
* @param {string} params.redirectUrl - Github Redirect URL as listed in your oauth app settings: {@link https://datasquirel.com/docs} * @param {string} params.redirectUrl - Github Redirect URL as listed in your oauth app settings: {@link https://datasquirel.com/docs}
* @param {function(boolean): void} [params.setLoading] - React setState Function: sets whether the google login button is ready or not * @param {function(boolean): void} [params.setLoading] - React setState Function: sets whether the google login button is ready or not
* @param {string[]} [params.scopes] - Scopes to be requested from the user * @param {string[]} [params.scopes] - Scopes to be requested from the user
* *
* @returns {void} - Return * @returns {void} - Return
*/ */
module.exports = function getAccessToken({ clientId, redirectUrl, setLoading, scopes }) { module.exports = function getAccessToken({ clientId, redirectUrl, setLoading, scopes }) {
/** /**
* == Initialize * == Initialize
* *
* @description Initialize * @description Initialize
*/ */
if (setLoading) setLoading(true); if (setLoading) setLoading(true);
const scopeString = scopes ? scopes.join("%20") : "read:user"; const scopeString = scopes ? scopes.join("%20") : "read:user";
const fetchUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&scope=${scopeString}&redirect_uri=${redirectUrl}`; const fetchUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&scope=${scopeString}&redirect_uri=${redirectUrl}`;
window.location.assign(fetchUrl); window.location.assign(fetchUrl);
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
}; };

View File

@ -1,113 +1,113 @@
/** /**
* Type Definitions * Type Definitions
* =============================================================================== * ===============================================================================
*/ */
/** /**
* @typedef {object} GoogleIdentityPromptNotification * @typedef {object} GoogleIdentityPromptNotification
* @property {function(): string} getMomentType - Notification moment type * @property {function(): string} getMomentType - Notification moment type
* @property {function(): string} getDismissedReason - Notification get Dismissed Reason * @property {function(): string} getDismissedReason - Notification get Dismissed Reason
* @property {function(): string} getNotDisplayedReason - Notification get Not Displayed Reason * @property {function(): string} getNotDisplayedReason - Notification get Not Displayed Reason
* @property {function(): string} getSkippedReason - Notification get Skipped Reason * @property {function(): string} getSkippedReason - Notification get Skipped Reason
* @property {function(): boolean} isDismissedMoment - Notification is Dismissed Moment * @property {function(): boolean} isDismissedMoment - Notification is Dismissed Moment
* @property {function(): boolean} isDisplayMoment - Notification is Display Moment * @property {function(): boolean} isDisplayMoment - Notification is Display Moment
* @property {function(): boolean} isDisplayed - Notification is Displayed * @property {function(): boolean} isDisplayed - Notification is Displayed
* @property {function(): boolean} isNotDisplayed - Notification is Not Displayed * @property {function(): boolean} isNotDisplayed - Notification is Not Displayed
* @property {function(): boolean} isSkippedMoment - Notification is Skipped Moment * @property {function(): boolean} isSkippedMoment - Notification is Skipped Moment
*/ */
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
/** /**
* Login with Google Function * Login with Google Function
* =============================================================================== * ===============================================================================
* @description This function uses google identity api to login a user with datasquirel * @description This function uses google identity api to login a user with datasquirel
* *
* @async * @async
* *
* @param {object} params - Single object passed * @param {object} params - Single object passed
* @param {string} params.clientId - Google app client ID: {@link https://datasquirel.com/docs} * @param {string} params.clientId - Google app client ID: {@link https://datasquirel.com/docs}
* @param {HTMLElement} params.element - HTML Element to display google login button * @param {HTMLElement} params.element - HTML Element to display google login button
* @param {boolean} params.triggerPrompt - Whether to trigger Google signing popup or not: {@link https://datasquirel.com/docs} * @param {boolean} params.triggerPrompt - Whether to trigger Google signing popup or not: {@link https://datasquirel.com/docs}
* @param {function(): void} [params.readyStateDispatch] - React setState Function: sets whether the google login button is ready or not * @param {function(): void} [params.readyStateDispatch] - React setState Function: sets whether the google login button is ready or not
* *
* @returns {Promise<boolean>} - Return * @returns {Promise<boolean>} - Return
*/ */
module.exports = async function getAccessToken({ clientId, element, triggerPrompt, readyStateDispatch }) { module.exports = async function getAccessToken({ clientId, element, triggerPrompt, readyStateDispatch }) {
/** /**
* == Initialize * == Initialize
* *
* @description Initialize * @description Initialize
*/ */
const googleScript = document.createElement("script"); const googleScript = document.createElement("script");
googleScript.src = "https://accounts.google.com/gsi/client"; googleScript.src = "https://accounts.google.com/gsi/client";
googleScript.className = "social-script-tag"; googleScript.className = "social-script-tag";
document.body.appendChild(googleScript); document.body.appendChild(googleScript);
const response = await new Promise((resolve, reject) => { const response = await new Promise((resolve, reject) => {
googleScript.onload = function (e) { googleScript.onload = function (e) {
if (google) { if (google) {
if (readyStateDispatch) readyStateDispatch(true); if (readyStateDispatch) readyStateDispatch(true);
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (element) { if (element) {
/** /**
* Handle google credentials response * Handle google credentials response
* ======================================================== * ========================================================
* @param {object} response - Google response with credentials * @param {object} response - Google response with credentials
* @param {string} response.credential - Google access token * @param {string} response.credential - Google access token
*/ */
function handleCredentialResponse(response) { function handleCredentialResponse(response) {
resolve(response.credential); resolve(response.credential);
} }
google.accounts.id.initialize({ google.accounts.id.initialize({
client_id: clientId, client_id: clientId,
callback: handleCredentialResponse, callback: handleCredentialResponse,
}); });
google.accounts.id.renderButton(element, { google.accounts.id.renderButton(element, {
theme: "outline", theme: "outline",
size: "large", size: "large",
logo_alignment: "center", logo_alignment: "center",
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (triggerPrompt) { if (triggerPrompt) {
google.accounts.id.prompt( google.accounts.id.prompt(
/** /**
* Google prompt notification callback * Google prompt notification callback
* ======================================================== * ========================================================
* @param {GoogleIdentityPromptNotification} notification - Notification object * @param {GoogleIdentityPromptNotification} notification - Notification object
*/ */
(notification) => { (notification) => {
notification.isDisplayed(); notification.isDisplayed();
} }
); );
} }
} }
}; };
}); });
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
return response; return response;
}; };

View File

@ -1,146 +1,146 @@
/** /**
* Type Definitions * Type Definitions
* =============================================================================== * ===============================================================================
*/ */
const parseClientCookies = require("../utils/parseClientCookies"); const parseClientCookies = require("../utils/parseClientCookies");
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
/** /**
* Login with Google Function * Login with Google Function
* =============================================================================== * ===============================================================================
* @description This function uses google identity api to login a user with datasquirel * @description This function uses google identity api to login a user with datasquirel
* *
* @async * @async
* *
* @param {object|null} params - Single object passed * @param {object|null} params - Single object passed
* @param {string|null} params.googleClientId - Google client Id if applicable * @param {string|null} params.googleClientId - Google client Id if applicable
* *
* @requires localStorageUser - a "user" JSON string stored in local storage with all * @requires localStorageUser - a "user" JSON string stored in local storage with all
* the necessary user data gotten from the server * the necessary user data gotten from the server
* *
* @returns {Promise<boolean>} - Return * @returns {Promise<boolean>} - Return
*/ */
module.exports = async function logout(params) { module.exports = async function logout(params) {
/** /**
* == Initialize * == Initialize
* *
* @description Initialize * @description Initialize
*/ */
const localUser = localStorage.getItem("user"); const localUser = localStorage.getItem("user");
let targetUser; let targetUser;
try { try {
targetUser = JSON.parse(localUser); targetUser = JSON.parse(localUser);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
if (!targetUser) { if (!targetUser) {
return false; return false;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const cookies = parseClientCookies(); const cookies = parseClientCookies();
const socialId = cookies?.datasquirel_social_id && typeof cookies.datasquirel_social_id == "string" && !cookies.datasquirel_social_id.match(/^null$/i) ? cookies.datasquirel_social_id : null; const socialId = cookies?.datasquirel_social_id && typeof cookies.datasquirel_social_id == "string" && !cookies.datasquirel_social_id.match(/^null$/i) ? cookies.datasquirel_social_id : null;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
localStorage.setItem("user", "{}"); localStorage.setItem("user", "{}");
localStorage.removeItem("csrf"); localStorage.removeItem("csrf");
document.cookie = `datasquirel_social_id=null;samesite=strict;path=/`; document.cookie = `datasquirel_social_id=null;samesite=strict;path=/`;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const response = await new Promise((resolve, reject) => { const response = await new Promise((resolve, reject) => {
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
if (socialId && !socialId?.match(/^null$/i)) { if (socialId && !socialId?.match(/^null$/i)) {
const googleClientId = params?.googleClientId; const googleClientId = params?.googleClientId;
if (googleClientId) { if (googleClientId) {
const googleScript = document.createElement("script"); const googleScript = document.createElement("script");
googleScript.src = "https://accounts.google.com/gsi/client"; googleScript.src = "https://accounts.google.com/gsi/client";
googleScript.className = "social-script-tag"; googleScript.className = "social-script-tag";
document.body.appendChild(googleScript); document.body.appendChild(googleScript);
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
googleScript.onload = function (e) { googleScript.onload = function (e) {
if (google) { if (google) {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
google.accounts.id.initialize({ google.accounts.id.initialize({
client_id: googleClientId, client_id: googleClientId,
}); });
google.accounts.id.revoke(socialId, (done) => { google.accounts.id.revoke(socialId, (done) => {
console.log(done.error); console.log(done.error);
resolve(true); resolve(true);
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} }
}; };
} else { } else {
resolve(true); resolve(true);
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} else { } else {
resolve(true); resolve(true);
} }
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
}); });
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
return response; return response;
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
}; };

View File

@ -1,47 +1,47 @@
// @ts-check // @ts-check
/** /**
* Imports * Imports
*/ */
const imageInputFileToBase64 = require("./media/imageInputFileToBase64"); const imageInputFileToBase64 = require("./media/imageInputFileToBase64");
const imageInputToBase64 = require("./media/imageInputToBase64"); const imageInputToBase64 = require("./media/imageInputToBase64");
const inputFileToBase64 = require("./media/inputFileToBase64"); const inputFileToBase64 = require("./media/inputFileToBase64");
const getAccessToken = require("./auth/google/getAccessToken"); const getAccessToken = require("./auth/google/getAccessToken");
const getGithubAccessToken = require("./auth/github/getAccessToken"); const getGithubAccessToken = require("./auth/github/getAccessToken");
const logout = require("./auth/logout"); const logout = require("./auth/logout");
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Media Functions Object * Media Functions Object
*/ */
const media = { const media = {
imageInputToBase64: imageInputToBase64, imageInputToBase64: imageInputToBase64,
imageInputFileToBase64: imageInputFileToBase64, imageInputFileToBase64: imageInputFileToBase64,
inputFileToBase64: inputFileToBase64, inputFileToBase64: inputFileToBase64,
}; };
/** /**
* User Auth Object * User Auth Object
*/ */
const auth = { const auth = {
google: { google: {
getAccessToken: getAccessToken, getAccessToken: getAccessToken,
}, },
github: { github: {
getAccessToken: getGithubAccessToken, getAccessToken: getGithubAccessToken,
}, },
logout: logout, logout: logout,
}; };
/** /**
* Main Export * Main Export
*/ */
const datasquirelClient = { const datasquirelClient = {
media: media, media: media,
auth: auth, auth: auth,
}; };
module.exports = datasquirelClient; module.exports = datasquirelClient;

View File

@ -1,49 +1,49 @@
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
import imageInputFileToBase64 from "./imageInputFileToBase64"; import imageInputFileToBase64 from "./imageInputFileToBase64";
import imageInputToBase64 from "./imageInputToBase64"; import imageInputToBase64 from "./imageInputToBase64";
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* ============================================================================== * ==============================================================================
* Media Functions Object * Media Functions Object
* ============================================================================== * ==============================================================================
*/ */
const media = { const media = {
imageInputToBase64: imageInputToBase64, imageInputToBase64: imageInputToBase64,
imageInputFileToBase64: imageInputFileToBase64, imageInputFileToBase64: imageInputFileToBase64,
}; };
/** /**
* ============================================================================== * ==============================================================================
* Media Functions Object * Media Functions Object
* ============================================================================== * ==============================================================================
*/ */
const auth = { const auth = {
imageInputToBase64: imageInputToBase64, imageInputToBase64: imageInputToBase64,
imageInputFileToBase64: imageInputFileToBase64, imageInputFileToBase64: imageInputFileToBase64,
}; };
/** /**
* ============================================================================== * ==============================================================================
* Main Export * Main Export
* ============================================================================== * ==============================================================================
*/ */
const datasquirelClient = { const datasquirelClient = {
media: media, media: media,
}; };
export default datasquirelClient; export default datasquirelClient;
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */

View File

@ -1,111 +1,111 @@
/** /**
* @typedef {{ * @typedef {{
* imageBase64: string, * imageBase64: string,
* imageBase64Full: string, * imageBase64Full: string,
* imageName: string, * imageName: string,
* imageSize: number, * imageSize: number,
* }} FunctionReturn * }} FunctionReturn
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {{ * @param {{
* imageInputFile: { name:string }, * imageInputFile: { name:string },
* maxWidth: number, * maxWidth: number,
* imagePreviewNode: HTMLImageElement, * imagePreviewNode: HTMLImageElement,
* }} params - Single object passed * }} params - Single object passed
* *
* @returns { Promise<FunctionReturn> } - Return Object * @returns { Promise<FunctionReturn> } - Return Object
*/ */
module.exports = async function imageInputFileToBase64({ imageInputFile, maxWidth, imagePreviewNode }) { module.exports = async function imageInputFileToBase64({ imageInputFile, maxWidth, imagePreviewNode }) {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
try { try {
let imageName = imageInputFile.name.replace(/\..*/, ""); let imageName = imageInputFile.name.replace(/\..*/, "");
let imageDataBase64; let imageDataBase64;
let imageSize; let imageSize;
let canvas = document.createElement("canvas"); let canvas = document.createElement("canvas");
const MIME_TYPE = imageInputFile.type; const MIME_TYPE = imageInputFile.type;
const QUALITY = 0.95; const QUALITY = 0.95;
const MAX_WIDTH = maxWidth ? maxWidth : null; const MAX_WIDTH = maxWidth ? maxWidth : null;
const file = imageInputFile; // get the file const file = imageInputFile; // get the file
const blobURL = URL.createObjectURL(file); const blobURL = URL.createObjectURL(file);
const img = new Image(); const img = new Image();
/** ********************* Add source to new image */ /** ********************* Add source to new image */
img.src = blobURL; img.src = blobURL;
imageDataBase64 = await new Promise((res, rej) => { imageDataBase64 = await new Promise((res, rej) => {
/** ********************* Handle Errors in loading image */ /** ********************* Handle Errors in loading image */
img.onerror = function () { img.onerror = function () {
URL.revokeObjectURL(this.src); URL.revokeObjectURL(this.src);
console.log("Cannot load image"); console.log("Cannot load image");
}; };
/** ********************* Handle new image when loaded */ /** ********************* Handle new image when loaded */
img.onload = function () { img.onload = function () {
URL.revokeObjectURL(this.src); URL.revokeObjectURL(this.src);
if (MAX_WIDTH) { if (MAX_WIDTH) {
const scaleSize = MAX_WIDTH / img.naturalWidth; const scaleSize = MAX_WIDTH / img.naturalWidth;
canvas.width = img.naturalWidth < MAX_WIDTH ? img.naturalWidth : MAX_WIDTH; canvas.width = img.naturalWidth < MAX_WIDTH ? img.naturalWidth : MAX_WIDTH;
canvas.height = img.naturalWidth < MAX_WIDTH ? img.naturalHeight : img.naturalHeight * scaleSize; canvas.height = img.naturalWidth < MAX_WIDTH ? img.naturalHeight : img.naturalHeight * scaleSize;
} else { } else {
canvas.width = img.naturalWidth; canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight; canvas.height = img.naturalHeight;
} }
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const srcEncoded = canvas.toDataURL(MIME_TYPE, QUALITY); const srcEncoded = canvas.toDataURL(MIME_TYPE, QUALITY);
if (imagePreviewNode) { if (imagePreviewNode) {
imagePreviewNode.src = srcEncoded; imagePreviewNode.src = srcEncoded;
} }
res(srcEncoded); res(srcEncoded);
}; };
}); });
imageSize = await new Promise((res, rej) => { imageSize = await new Promise((res, rej) => {
canvas.toBlob( canvas.toBlob(
(blob) => { (blob) => {
res(blob.size); res(blob.size);
}, },
MIME_TYPE, MIME_TYPE,
QUALITY QUALITY
); );
}); });
return { return {
imageBase64: imageDataBase64.replace(/.*?base64,/, ""), imageBase64: imageDataBase64.replace(/.*?base64,/, ""),
imageBase64Full: imageDataBase64, imageBase64Full: imageDataBase64,
imageName: imageName, imageName: imageName,
imageSize: imageSize, imageSize: imageSize,
}; };
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Image Processing Error! =>", error.message); console.log("Image Processing Error! =>", error.message);
return { return {
imageBase64: null, imageBase64: null,
imageBase64Full: null, imageBase64Full: null,
imageName: null, imageName: null,
imageSize: null, imageSize: null,
}; };
} }
}; };
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */

View File

@ -1,101 +1,101 @@
/** /**
* @typedef {{ * @typedef {{
* imageBase64: string, * imageBase64: string,
* imageBase64Full: string, * imageBase64Full: string,
* imageName: string, * imageName: string,
* }} FunctionReturn * }} FunctionReturn
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {{ * @param {{
* imageInput: HTMLInputElement, * imageInput: HTMLInputElement,
* maxWidth: number, * maxWidth: number,
* mimeType: [string='image/jpeg'] * mimeType: [string='image/jpeg']
* }} params - Single object passed * }} params - Single object passed
* *
* @returns { Promise<FunctionReturn> } - Return Object * @returns { Promise<FunctionReturn> } - Return Object
*/ */
module.exports = async function imageInputToBase64({ imageInput, maxWidth, mimeType }) { module.exports = async function imageInputToBase64({ imageInput, maxWidth, mimeType }) {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
try { try {
let imagePreviewNode = document.querySelector(`[data-imagepreview='image']`); let imagePreviewNode = document.querySelector(`[data-imagepreview='image']`);
let imageName = imageInput.files[0].name.replace(/\..*/, ""); let imageName = imageInput.files[0].name.replace(/\..*/, "");
let imageDataBase64; let imageDataBase64;
const MIME_TYPE = mimeType ? mimeType : "image/jpeg"; const MIME_TYPE = mimeType ? mimeType : "image/jpeg";
const QUALITY = 0.95; const QUALITY = 0.95;
const MAX_WIDTH = maxWidth ? maxWidth : null; const MAX_WIDTH = maxWidth ? maxWidth : null;
const file = imageInput.files[0]; // get the file const file = imageInput.files[0]; // get the file
const blobURL = URL.createObjectURL(file); const blobURL = URL.createObjectURL(file);
const img = new Image(); const img = new Image();
/** ********************* Add source to new image */ /** ********************* Add source to new image */
img.src = blobURL; img.src = blobURL;
imageDataBase64 = await new Promise((res, rej) => { imageDataBase64 = await new Promise((res, rej) => {
/** ********************* Handle Errors in loading image */ /** ********************* Handle Errors in loading image */
img.onerror = function () { img.onerror = function () {
URL.revokeObjectURL(this.src); URL.revokeObjectURL(this.src);
window.alert("Cannot load image!"); window.alert("Cannot load image!");
}; };
/** ********************* Handle new image when loaded */ /** ********************* Handle new image when loaded */
img.onload = function () { img.onload = function () {
URL.revokeObjectURL(this.src); URL.revokeObjectURL(this.src);
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
if (MAX_WIDTH) { if (MAX_WIDTH) {
const scaleSize = MAX_WIDTH / img.naturalWidth; const scaleSize = MAX_WIDTH / img.naturalWidth;
canvas.width = img.naturalWidth < MAX_WIDTH ? img.naturalWidth : MAX_WIDTH; canvas.width = img.naturalWidth < MAX_WIDTH ? img.naturalWidth : MAX_WIDTH;
canvas.height = img.naturalWidth < MAX_WIDTH ? img.naturalHeight : img.naturalHeight * scaleSize; canvas.height = img.naturalWidth < MAX_WIDTH ? img.naturalHeight : img.naturalHeight * scaleSize;
} else { } else {
canvas.width = img.naturalWidth; canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight; canvas.height = img.naturalHeight;
} }
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const srcEncoded = canvas.toDataURL(MIME_TYPE, QUALITY); const srcEncoded = canvas.toDataURL(MIME_TYPE, QUALITY);
if (imagePreviewNode) { if (imagePreviewNode) {
document.querySelectorAll(`[data-imagepreview='image']`).forEach((img) => { document.querySelectorAll(`[data-imagepreview='image']`).forEach((img) => {
img.src = srcEncoded; img.src = srcEncoded;
}); });
} }
res(srcEncoded); res(srcEncoded);
}; };
}); });
return { return {
imageBase64: imageDataBase64.replace(/.*?base64,/, ""), imageBase64: imageDataBase64.replace(/.*?base64,/, ""),
imageBase64Full: imageDataBase64, imageBase64Full: imageDataBase64,
imageName: imageName, imageName: imageName,
}; };
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Image Processing Error! =>", error.message); console.log("Image Processing Error! =>", error.message);
return { return {
imageBase64: null, imageBase64: null,
imageBase64Full: null, imageBase64Full: null,
imageName: null, imageName: null,
}; };
} }
}; };
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */

View File

@ -1,96 +1,96 @@
/** /**
* @typedef {{ * @typedef {{
* fileBase64: string, * fileBase64: string,
* fileBase64Full: string, * fileBase64Full: string,
* fileName: string, * fileName: string,
* fileSize: number, * fileSize: number,
* fileType: string, * fileType: string,
* }} FunctionReturn * }} FunctionReturn
*/ */
/** /**
* Input File to base64 * Input File to base64
* ============================================================================== * ==============================================================================
* *
* @description This function takes in a *SINGLE* input file from a HTML file input element. * @description This function takes in a *SINGLE* input file from a HTML file input element.
* HTML file input elements usually return an array of input objects, so be sure to select the target * HTML file input elements usually return an array of input objects, so be sure to select the target
* file from the array. * file from the array.
* *
* @async * @async
* *
* @param {object} params - Single object passed * @param {object} params - Single object passed
* @param {object} params.inputFile - HTML input File * @param {object} params.inputFile - HTML input File
* @param {string} params.inputFile.name - Input File Name * @param {string} params.inputFile.name - Input File Name
* @param {number} params.inputFile.size - Input File Size in bytes * @param {number} params.inputFile.size - Input File Size in bytes
* @param {string} params.inputFile.type - Input File Type: "JPEG", "PNG", "PDF", etc. Whichever allowed regexp is provided * @param {string} params.inputFile.type - Input File Type: "JPEG", "PNG", "PDF", etc. Whichever allowed regexp is provided
* @param {RegExp} [params.allowedRegex] - Regexp containing the allowed file types * @param {RegExp} [params.allowedRegex] - Regexp containing the allowed file types
* *
* @returns { Promise<FunctionReturn> } - Return Object * @returns { Promise<FunctionReturn> } - Return Object
*/ */
module.exports = async function inputFileToBase64({ inputFile, allowedRegex }) { module.exports = async function inputFileToBase64({ inputFile, allowedRegex }) {
/** /**
* == Initialize * == Initialize
* *
* @description Initialize * @description Initialize
*/ */
const allowedTypesRegex = allowedRegex ? allowedRegex : /image\/*|\/pdf/; const allowedTypesRegex = allowedRegex ? allowedRegex : /image\/*|\/pdf/;
if (!inputFile?.type?.match(allowedTypesRegex)) { if (!inputFile?.type?.match(allowedTypesRegex)) {
window.alert(`We currently don't support ${inputFile.type} file types. Support is coming soon. For now we support only images and PDFs.`); window.alert(`We currently don't support ${inputFile.type} file types. Support is coming soon. For now we support only images and PDFs.`);
return { return {
fileBase64: null, fileBase64: null,
fileBase64Full: null, fileBase64Full: null,
fileName: inputFile.name, fileName: inputFile.name,
fileSize: null, fileSize: null,
fileType: null, fileType: null,
}; };
} }
try { try {
/** Process File **/ /** Process File **/
let fileName = inputFile.name.replace(/\..*/, ""); let fileName = inputFile.name.replace(/\..*/, "");
/** Add source to new file **/ /** Add source to new file **/
const fileData = await new Promise((resolve, reject) => { const fileData = await new Promise((resolve, reject) => {
var reader = new FileReader(); var reader = new FileReader();
reader.readAsDataURL(inputFile); reader.readAsDataURL(inputFile);
reader.onload = function () { reader.onload = function () {
resolve(reader.result); resolve(reader.result);
}; };
reader.onerror = function (/** @type {*} */ error) { reader.onerror = function (/** @type {*} */ error) {
console.log("Error: ", error.message); console.log("Error: ", error.message);
}; };
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return { return {
fileBase64: fileData.replace(/.*?base64,/, ""), fileBase64: fileData.replace(/.*?base64,/, ""),
fileBase64Full: fileData, fileBase64Full: fileData,
fileName: fileName, fileName: fileName,
fileSize: inputFile.size, fileSize: inputFile.size,
fileType: inputFile.type, fileType: inputFile.type,
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("File Processing Error! =>", error.message); console.log("File Processing Error! =>", error.message);
return { return {
fileBase64: null, fileBase64: null,
fileBase64Full: null, fileBase64Full: null,
fileName: inputFile.name, fileName: inputFile.name,
fileSize: null, fileSize: null,
fileType: null, fileType: null,
}; };
} }
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -1,65 +1,65 @@
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
/** /**
* Parse request cookies * Parse request cookies
* ============================================================================== * ==============================================================================
* *
* @description This function takes in a request object and returns the cookies as a JS object * @description This function takes in a request object and returns the cookies as a JS object
* *
* @async * @async
* *
* @param {object} params - main params object * @param {object} params - main params object
* @param {object} params.request - HTTPS request object * @param {object} params.request - HTTPS request object
* *
* @returns {{}|null} * @returns {{}|null}
*/ */
module.exports = function () { module.exports = function () {
/** /**
* Check inputs * Check inputs
* *
* @description Check inputs * @description Check inputs
*/ */
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** @type {string|null} */ /** @type {string|null} */
const cookieString = document.cookie; const cookieString = document.cookie;
if (!cookieString || typeof cookieString !== "string") { if (!cookieString || typeof cookieString !== "string") {
return null; return null;
} }
/** @type {string[]} */ /** @type {string[]} */
const cookieSplitArray = cookieString.split(";"); const cookieSplitArray = cookieString.split(";");
let cookieObject = {}; let cookieObject = {};
cookieSplitArray.forEach((keyValueString) => { cookieSplitArray.forEach((keyValueString) => {
const [key, value] = keyValueString.split("="); const [key, value] = keyValueString.split("=");
if (key && typeof key == "string") { if (key && typeof key == "string") {
cookieObject[key.replace(/^ +| +$/, "")] = value && typeof value == "string" ? value.replace(/^ +| +$/, "") : null; cookieObject[key.replace(/^ +| +$/, "")] = value && typeof value == "string" ? value.replace(/^ +| +$/, "") : null;
} }
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
return cookieObject; return cookieObject;
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -1,31 +1,31 @@
const colors = { const colors = {
Reset: "\x1b[0m", Reset: "\x1b[0m",
Bright: "\x1b[1m", Bright: "\x1b[1m",
Dim: "\x1b[2m", Dim: "\x1b[2m",
Underscore: "\x1b[4m", Underscore: "\x1b[4m",
Blink: "\x1b[5m", Blink: "\x1b[5m",
Reverse: "\x1b[7m", Reverse: "\x1b[7m",
Hidden: "\x1b[8m", Hidden: "\x1b[8m",
FgBlack: "\x1b[30m", FgBlack: "\x1b[30m",
FgRed: "\x1b[31m", FgRed: "\x1b[31m",
FgGreen: "\x1b[32m", FgGreen: "\x1b[32m",
FgYellow: "\x1b[33m", FgYellow: "\x1b[33m",
FgBlue: "\x1b[34m", FgBlue: "\x1b[34m",
FgMagenta: "\x1b[35m", FgMagenta: "\x1b[35m",
FgCyan: "\x1b[36m", FgCyan: "\x1b[36m",
FgWhite: "\x1b[37m", FgWhite: "\x1b[37m",
FgGray: "\x1b[90m", FgGray: "\x1b[90m",
BgBlack: "\x1b[40m", BgBlack: "\x1b[40m",
BgRed: "\x1b[41m", BgRed: "\x1b[41m",
BgGreen: "\x1b[42m", BgGreen: "\x1b[42m",
BgYellow: "\x1b[43m", BgYellow: "\x1b[43m",
BgBlue: "\x1b[44m", BgBlue: "\x1b[44m",
BgMagenta: "\x1b[45m", BgMagenta: "\x1b[45m",
BgCyan: "\x1b[46m", BgCyan: "\x1b[46m",
BgWhite: "\x1b[47m", BgWhite: "\x1b[47m",
BgGray: "\x1b[100m", BgGray: "\x1b[100m",
}; };
module.exports = colors; module.exports = colors;

View File

@ -1,116 +1,116 @@
#! /usr/bin/env node #! /usr/bin/env node
// @ts-check // @ts-check
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const { execSync } = require("child_process"); const { execSync } = require("child_process");
require("dotenv").config({ require("dotenv").config({
path: path.resolve(process.cwd(), ".env"), path: path.resolve(process.cwd(), ".env"),
}); });
const datasquirel = require("../index"); const datasquirel = require("../index");
const createDbFromSchema = require("./engine/createDbFromSchema"); const createDbFromSchema = require("./engine/createDbFromSchema");
const colors = require("../console-colors"); const colors = require("../console-colors");
if (!fs.existsSync(path.resolve(process.cwd(), ".env"))) { if (!fs.existsSync(path.resolve(process.cwd(), ".env"))) {
console.log(".env file not found"); console.log(".env file not found");
process.exit(); process.exit();
} }
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC, DSQL_ENCRYPTION_KEY, DSQL_ENCRYPTION_SALT } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC, DSQL_ENCRYPTION_KEY, DSQL_ENCRYPTION_SALT } = process.env;
if (!DSQL_HOST?.match(/./)) { if (!DSQL_HOST?.match(/./)) {
console.log("DSQL_HOST is required in your `.env` file"); console.log("DSQL_HOST is required in your `.env` file");
process.exit(); process.exit();
} }
if (!DSQL_USER?.match(/./)) { if (!DSQL_USER?.match(/./)) {
console.log("DSQL_USER is required in your `.env` file"); console.log("DSQL_USER is required in your `.env` file");
process.exit(); process.exit();
} }
if (!DSQL_PASS?.match(/./)) { if (!DSQL_PASS?.match(/./)) {
console.log("DSQL_PASS is required in your `.env` file"); console.log("DSQL_PASS is required in your `.env` file");
process.exit(); process.exit();
} }
const dbSchemaLocalFilePath = path.resolve(process.cwd(), "dsql.schema.json"); const dbSchemaLocalFilePath = path.resolve(process.cwd(), "dsql.schema.json");
async function run() { async function run() {
let schemaData; let schemaData;
if (DSQL_KEY && DSQL_REF_DB_NAME?.match(/./)) { if (DSQL_KEY && DSQL_REF_DB_NAME?.match(/./)) {
const dbSchemaDataResponse = await datasquirel.getSchema({ const dbSchemaDataResponse = await datasquirel.getSchema({
key: DSQL_KEY, key: DSQL_KEY,
database: DSQL_REF_DB_NAME || undefined, database: DSQL_REF_DB_NAME || undefined,
}); });
if (!dbSchemaDataResponse.payload || Array.isArray(dbSchemaDataResponse.payload)) { if (!dbSchemaDataResponse.payload || Array.isArray(dbSchemaDataResponse.payload)) {
console.log("DSQL_KEY+DSQL_REF_DB_NAME => Error in fetching DB schema"); console.log("DSQL_KEY+DSQL_REF_DB_NAME => Error in fetching DB schema");
console.log(dbSchemaDataResponse); console.log(dbSchemaDataResponse);
process.exit(); process.exit();
} }
let fetchedDbSchemaObject = dbSchemaDataResponse.payload; let fetchedDbSchemaObject = dbSchemaDataResponse.payload;
if (DSQL_DB_NAME) fetchedDbSchemaObject.dbFullName = DSQL_DB_NAME; if (DSQL_DB_NAME) fetchedDbSchemaObject.dbFullName = DSQL_DB_NAME;
schemaData = [fetchedDbSchemaObject]; schemaData = [fetchedDbSchemaObject];
} else if (DSQL_KEY) { } else if (DSQL_KEY) {
const dbSchemaDataResponse = await datasquirel.getSchema({ const dbSchemaDataResponse = await datasquirel.getSchema({
key: DSQL_KEY, key: DSQL_KEY,
database: DSQL_REF_DB_NAME || undefined, database: DSQL_REF_DB_NAME || undefined,
}); });
if (!dbSchemaDataResponse.payload || !Array.isArray(dbSchemaDataResponse.payload)) { if (!dbSchemaDataResponse.payload || !Array.isArray(dbSchemaDataResponse.payload)) {
console.log("DSQL_KEY => Error in fetching DB schema"); console.log("DSQL_KEY => Error in fetching DB schema");
console.log(dbSchemaDataResponse); console.log(dbSchemaDataResponse);
process.exit(); process.exit();
} }
let fetchedDbSchemaObject = dbSchemaDataResponse.payload; let fetchedDbSchemaObject = dbSchemaDataResponse.payload;
// fetchedDbSchemaObject.forEach((db, index) => { // fetchedDbSchemaObject.forEach((db, index) => {
// db.dbFullName = db.dbFullName?.replace(/^datasquirel_user_\d+_/, ""); // db.dbFullName = db.dbFullName?.replace(/^datasquirel_user_\d+_/, "");
// }); // });
schemaData = fetchedDbSchemaObject; schemaData = fetchedDbSchemaObject;
} else if (fs.existsSync(dbSchemaLocalFilePath)) { } else if (fs.existsSync(dbSchemaLocalFilePath)) {
schemaData = [JSON.parse(fs.readFileSync(dbSchemaLocalFilePath, "utf8"))]; schemaData = [JSON.parse(fs.readFileSync(dbSchemaLocalFilePath, "utf8"))];
} else { } else {
console.log("No source for DB Schema. Please provide a local `dsql.schema.json` file, or provide `DSQL_KEY` and `DSQL_REF_DB_NAME` environment variables."); console.log("No source for DB Schema. Please provide a local `dsql.schema.json` file, or provide `DSQL_KEY` and `DSQL_REF_DB_NAME` environment variables.");
process.exit(); process.exit();
} }
if (!schemaData) { if (!schemaData) {
console.log("No schema found"); console.log("No schema found");
process.exit(); process.exit();
} }
if (DSQL_FULL_SYNC?.match(/true/i)) { if (DSQL_FULL_SYNC?.match(/true/i)) {
fs.writeFileSync(dbSchemaLocalFilePath, JSON.stringify(schemaData[0], null, 4), "utf8"); fs.writeFileSync(dbSchemaLocalFilePath, JSON.stringify(schemaData[0], null, 4), "utf8");
} }
console.log(` - ${colors.FgBlue}Info:${colors.Reset} Now generating and mapping databases ...`); console.log(` - ${colors.FgBlue}Info:${colors.Reset} Now generating and mapping databases ...`);
// deepcode ignore reDOS: <please specify a reason of ignoring this> // deepcode ignore reDOS: <please specify a reason of ignoring this>
await createDbFromSchema(schemaData); await createDbFromSchema(schemaData);
console.log(` - ${colors.FgGreen}Success:${colors.Reset} Databases created Successfully!`); console.log(` - ${colors.FgGreen}Success:${colors.Reset} Databases created Successfully!`);
} }
// let timeout; // let timeout;
let interval; let interval;
if (fs.existsSync(dbSchemaLocalFilePath) && !DSQL_KEY?.match(/....../)) { if (fs.existsSync(dbSchemaLocalFilePath) && !DSQL_KEY?.match(/....../)) {
fs.watchFile(dbSchemaLocalFilePath, { interval: 1000 }, (curr, prev) => { fs.watchFile(dbSchemaLocalFilePath, { interval: 1000 }, (curr, prev) => {
console.log(` - ${colors.FgBlue}Info:${colors.Reset} Syncing Databases Locally ...`); console.log(` - ${colors.FgBlue}Info:${colors.Reset} Syncing Databases Locally ...`);
run(); run();
}); });
} else if (DSQL_KEY?.match(/....../)) { } else if (DSQL_KEY?.match(/....../)) {
interval = setInterval(() => { interval = setInterval(() => {
console.log(` - ${colors.FgMagenta}Info:${colors.Reset} Syncing Databases from the cloud ...`); console.log(` - ${colors.FgMagenta}Info:${colors.Reset} Syncing Databases from the cloud ...`);
run(); run();
}, 20000); }, 20000);
} }
run(); run();

View File

@ -1,53 +1,53 @@
#! /usr/bin/env node #! /usr/bin/env node
// @ts-check // @ts-check
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const { execSync } = require("child_process"); const { execSync } = require("child_process");
require("dotenv").config({ require("dotenv").config({
path: path.resolve(process.cwd(), ".env"), path: path.resolve(process.cwd(), ".env"),
}); });
const mysqlPath = process.platform?.match(/win/i) ? "'" + "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysql.exe" + "'" : "mysql"; const mysqlPath = process.platform?.match(/win/i) ? "'" + "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysql.exe" + "'" : "mysql";
const mysqlDumpPath = process.platform?.match(/win/i) ? "'" + "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqldump.exe" + "'" : "mysqldump"; const mysqlDumpPath = process.platform?.match(/win/i) ? "'" + "C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqldump.exe" + "'" : "mysqldump";
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC, DSQL_ENCRYPTION_KEY, DSQL_ENCRYPTION_SALT } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC, DSQL_ENCRYPTION_KEY, DSQL_ENCRYPTION_SALT } = process.env;
const dbName = DSQL_DB_NAME || ""; const dbName = DSQL_DB_NAME || "";
const dumpFilePathArg = process.argv.indexOf("--file"); const dumpFilePathArg = process.argv.indexOf("--file");
if (dumpFilePathArg < 0) { if (dumpFilePathArg < 0) {
console.log("Please provide a dump file path using `--file` argument"); console.log("Please provide a dump file path using `--file` argument");
process.exit(); process.exit();
} }
const dumpFilePath = process.argv[dumpFilePathArg + 1]; const dumpFilePath = process.argv[dumpFilePathArg + 1];
if (!dbName?.match(/./)) { if (!dbName?.match(/./)) {
console.log("DSQL_DB_NAME is required in your `.env` file"); console.log("DSQL_DB_NAME is required in your `.env` file");
process.exit(); process.exit();
} }
if (!DSQL_USER?.match(/./) || !DSQL_PASS?.match(/./)) { if (!DSQL_USER?.match(/./) || !DSQL_PASS?.match(/./)) {
console.log("DSQL_USER and DSQL_PASS are required in your `.env` file"); console.log("DSQL_USER and DSQL_PASS are required in your `.env` file");
process.exit(); process.exit();
} }
try { try {
let execSyncOptions = { let execSyncOptions = {
cwd: process.cwd(), cwd: process.cwd(),
}; };
if (process.platform.match(/win/i)) execSyncOptions.shell = "bash.exe"; if (process.platform.match(/win/i)) execSyncOptions.shell = "bash.exe";
const dump = execSync(`${mysqlPath} -u ${DSQL_USER} -p${DSQL_PASS} ${dbName} < ${dumpFilePath}`, execSyncOptions); const dump = execSync(`${mysqlPath} -u ${DSQL_USER} -p${DSQL_PASS} ${dbName} < ${dumpFilePath}`, execSyncOptions);
console.log("Dumped successfully", dump.toString()); console.log("Dumped successfully", dump.toString());
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Dump Error: ", error.message); console.log("Dump Error: ", error.message);
} }

View File

@ -1,77 +1,77 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const { execSync } = require("child_process"); const { execSync } = require("child_process");
const updateApiSchemaFromLocalDb = require("../query/update-api-schema-from-local-db"); const updateApiSchemaFromLocalDb = require("../query/update-api-schema-from-local-db");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* Add `users` table to user database * Add `users` table to user database
* ============================================================================== * ==============================================================================
* *
* @param {object} params - Single object passed * @param {object} params - Single object passed
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema - Database Schema Object * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema - Database Schema Object
* *
* @returns {Promise<*>} new user auth object payload * @returns {Promise<*>} new user auth object payload
*/ */
module.exports = async function addUsersTableToDb({ dbSchema }) { module.exports = async function addUsersTableToDb({ dbSchema }) {
/** /**
* Initialize * Initialize
* *
* @description Initialize * @description Initialize
*/ */
const database = process.env.DSQL_DB_NAME || ""; const database = process.env.DSQL_DB_NAME || "";
/** @type {import("../../types/database-schema.td").DSQL_TableSchemaType} */ /** @type {import("../../types/database-schema.td").DSQL_TableSchemaType} */
const userPreset = require("./data/presets/users.json"); const userPreset = require("./data/presets/users.json");
try { try {
/** /**
* Fetch user * Fetch user
* *
* @description Fetch user from db * @description Fetch user from db
*/ */
const userSchemaMainFilePath = path.resolve(process.cwd(), "dsql.schema.json"); const userSchemaMainFilePath = path.resolve(process.cwd(), "dsql.schema.json");
let targetDatabase = dbSchema; let targetDatabase = dbSchema;
let existingTableIndex = targetDatabase.tables.findIndex((table, index) => { let existingTableIndex = targetDatabase.tables.findIndex((table, index) => {
if (table.tableName === "users") { if (table.tableName === "users") {
existingTableIndex = index; existingTableIndex = index;
return true; return true;
} }
}); });
if (existingTableIndex >= 0) { if (existingTableIndex >= 0) {
targetDatabase.tables[existingTableIndex] = userPreset; targetDatabase.tables[existingTableIndex] = userPreset;
} else { } else {
targetDatabase.tables.push(userPreset); targetDatabase.tables.push(userPreset);
} }
fs.writeFileSync(`${userSchemaMainFilePath}`, JSON.stringify(dbSchema, null, 4), "utf8"); fs.writeFileSync(`${userSchemaMainFilePath}`, JSON.stringify(dbSchema, null, 4), "utf8");
//////////////////////////////////////// ////////////////////////////////////////
await updateApiSchemaFromLocalDb(); await updateApiSchemaFromLocalDb();
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log(error.message); console.log(error.message);
} }
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -1,257 +1,257 @@
// @ts-check // @ts-check
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const path = require("path"); const path = require("path");
//////////////////////////////////////// ////////////////////////////////////////
const noDatabaseDbHandler = require("./utils/noDatabaseDbHandler"); const noDatabaseDbHandler = require("./utils/noDatabaseDbHandler");
const varDatabaseDbHandler = require("./utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("./utils/varDatabaseDbHandler");
const createTable = require("./utils/createTable"); const createTable = require("./utils/createTable");
const updateTable = require("./utils/updateTable"); const updateTable = require("./utils/updateTable");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* Create database from Schema * Create database from Schema
* ============================================================================== * ==============================================================================
* @description Create database from Schema. This function is called when the user * @description Create database from Schema. This function is called when the user
* runs the "dsql create" command. `NOTE`: there must be a "dsql.schema.json" file * runs the "dsql create" command. `NOTE`: there must be a "dsql.schema.json" file
* in the root of the project for this function to work * in the root of the project for this function to work
* *
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType[]} dbSchema - An array of database schema objects * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType[]} dbSchema - An array of database schema objects
*/ */
async function createDbFromSchema(dbSchema) { async function createDbFromSchema(dbSchema) {
try { try {
/** /**
* Grab Schema * Grab Schema
* *
* @description Grab Schema * @description Grab Schema
*/ */
if (!dbSchema || !Array.isArray(dbSchema) || !dbSchema[0]) { if (!dbSchema || !Array.isArray(dbSchema) || !dbSchema[0]) {
return; return;
} }
for (let i = 0; i < dbSchema.length; i++) { for (let i = 0; i < dbSchema.length; i++) {
/** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} */ /** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} */
const database = dbSchema[i]; const database = dbSchema[i];
const { dbFullName, tables } = database; const { dbFullName, tables } = database;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** @type {{ dbFullName: string }[] | null} */ /** @type {{ dbFullName: string }[] | null} */
const dbCheck = await noDatabaseDbHandler({ query: `SELECT SCHEMA_NAME AS dbFullName FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${dbFullName}'` }); const dbCheck = await noDatabaseDbHandler({ query: `SELECT SCHEMA_NAME AS dbFullName FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${dbFullName}'` });
if (dbCheck && dbCheck[0]?.dbFullName) { if (dbCheck && dbCheck[0]?.dbFullName) {
// Database Exists // Database Exists
} else { } else {
const newDatabase = await noDatabaseDbHandler({ query: `CREATE DATABASE IF NOT EXISTS \`${dbFullName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin` }); const newDatabase = await noDatabaseDbHandler({ query: `CREATE DATABASE IF NOT EXISTS \`${dbFullName}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin` });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Select all tables * Select all tables
* @type {{ TABLE_NAME: string }[] | null} * @type {{ TABLE_NAME: string }[] | null}
* @description Select All tables in target database * @description Select All tables in target database
*/ */
const allTables = await noDatabaseDbHandler({ query: `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='${dbFullName}'` }); const allTables = await noDatabaseDbHandler({ query: `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='${dbFullName}'` });
let tableDropped; let tableDropped;
if (!allTables) { if (!allTables) {
console.log("No Tables to Update"); console.log("No Tables to Update");
continue; continue;
} }
for (let tb = 0; tb < allTables.length; tb++) { for (let tb = 0; tb < allTables.length; tb++) {
const { TABLE_NAME } = allTables[tb]; const { TABLE_NAME } = allTables[tb];
/** /**
* @description Check if TABLE_NAME is part of the tables contained * @description Check if TABLE_NAME is part of the tables contained
* in the user schema JSON. If it's not, the table is either deleted * in the user schema JSON. If it's not, the table is either deleted
* or the table name has been recently changed * or the table name has been recently changed
*/ */
if (!tables.filter((_table) => _table.tableName === TABLE_NAME)[0]) { if (!tables.filter((_table) => _table.tableName === TABLE_NAME)[0]) {
const oldTableFilteredArray = tables.filter((_table) => _table.tableNameOld && _table.tableNameOld === TABLE_NAME); const oldTableFilteredArray = tables.filter((_table) => _table.tableNameOld && _table.tableNameOld === TABLE_NAME);
/** /**
* @description Check if this table has been recently renamed. Rename * @description Check if this table has been recently renamed. Rename
* table id true. Drop table if false * table id true. Drop table if false
*/ */
if (oldTableFilteredArray && oldTableFilteredArray[0]) { if (oldTableFilteredArray && oldTableFilteredArray[0]) {
console.log("Renaming Table"); console.log("Renaming Table");
await varDatabaseDbHandler({ await varDatabaseDbHandler({
queryString: `RENAME TABLE \`${oldTableFilteredArray[0].tableNameOld}\` TO \`${oldTableFilteredArray[0].tableName}\``, queryString: `RENAME TABLE \`${oldTableFilteredArray[0].tableNameOld}\` TO \`${oldTableFilteredArray[0].tableName}\``,
database: dbFullName, database: dbFullName,
}); });
} else { } else {
console.log(`Dropping Table from ${dbFullName}`); console.log(`Dropping Table from ${dbFullName}`);
// deepcode ignore reDOS: <NO user input> // deepcode ignore reDOS: <NO user input>
await varDatabaseDbHandler({ await varDatabaseDbHandler({
queryString: `DROP TABLE \`${TABLE_NAME}\``, queryString: `DROP TABLE \`${TABLE_NAME}\``,
database: dbFullName, database: dbFullName,
}); });
tableDropped = true; tableDropped = true;
} }
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Iterate through each table and perform table actions * @description Iterate through each table and perform table actions
*/ */
for (let t = 0; t < tables.length; t++) { for (let t = 0; t < tables.length; t++) {
const table = tables[t]; const table = tables[t];
if (tableDropped) continue; if (tableDropped) continue;
const { tableName, fields, indexes } = table; const { tableName, fields, indexes } = table;
/** /**
* @description Check if table exists * @description Check if table exists
*/ */
const tableCheck = await varDatabaseDbHandler({ const tableCheck = await varDatabaseDbHandler({
queryString: ` queryString: `
SELECT EXISTS ( SELECT EXISTS (
SELECT SELECT
TABLE_NAME TABLE_NAME
FROM FROM
information_schema.TABLES information_schema.TABLES
WHERE WHERE
TABLE_SCHEMA = ? AND TABLE_SCHEMA = ? AND
TABLE_NAME = ? TABLE_NAME = ?
) AS tableExists`, ) AS tableExists`,
queryValuesArray: [dbFullName, table.tableName], queryValuesArray: [dbFullName, table.tableName],
database: dbFullName, database: dbFullName,
}); });
//////////////////////////////////////// ////////////////////////////////////////
if (tableCheck && tableCheck[0]?.tableExists > 0) { if (tableCheck && tableCheck[0]?.tableExists > 0) {
/** /**
* @description Update table if table exists * @description Update table if table exists
*/ */
const updateExistingTable = await updateTable({ const updateExistingTable = await updateTable({
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: tableName, tableName: tableName,
tableInfoArray: fields, tableInfoArray: fields,
dbSchema, dbSchema,
tableIndexes: indexes, tableIndexes: indexes,
tableIndex: t, tableIndex: t,
}); });
if (table.childrenTables && table.childrenTables[0]) { if (table.childrenTables && table.childrenTables[0]) {
for (let ch = 0; ch < table.childrenTables.length; ch++) { for (let ch = 0; ch < table.childrenTables.length; ch++) {
const childTable = table.childrenTables[ch]; const childTable = table.childrenTables[ch];
const updateExistingChildTable = await updateTable({ const updateExistingChildTable = await updateTable({
dbFullName: childTable.dbNameFull, dbFullName: childTable.dbNameFull,
tableName: childTable.tableName, tableName: childTable.tableName,
tableInfoArray: fields, tableInfoArray: fields,
dbSchema, dbSchema,
tableIndexes: indexes, tableIndexes: indexes,
clone: true, clone: true,
}); });
// console.log(updateExistingChildTable); // console.log(updateExistingChildTable);
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
} else { } else {
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Create new Table if table doesnt exist * @description Create new Table if table doesnt exist
*/ */
const createNewTable = await createTable({ const createNewTable = await createTable({
tableName: tableName, tableName: tableName,
tableInfoArray: fields, tableInfoArray: fields,
varDatabaseDbHandler, varDatabaseDbHandler,
dbFullName: dbFullName, dbFullName: dbFullName,
dbSchema, dbSchema,
}); });
if (indexes && indexes[0]) { if (indexes && indexes[0]) {
/** /**
* Handle DATASQUIREL Table Indexes * Handle DATASQUIREL Table Indexes
* =================================================== * ===================================================
* @description Iterate through each datasquirel schema * @description Iterate through each datasquirel schema
* table index(if available), and perform operations * table index(if available), and perform operations
*/ */
if (indexes && indexes[0]) { if (indexes && indexes[0]) {
for (let g = 0; g < indexes.length; g++) { for (let g = 0; g < indexes.length; g++) {
const { indexType, indexName, indexTableFields, alias } = indexes[g]; const { indexType, indexName, indexTableFields, alias } = indexes[g];
if (!alias?.match(/./)) continue; if (!alias?.match(/./)) continue;
/** /**
* @type {any[] | null} * @type {any[] | null}
* @description All indexes from MYSQL db * @description All indexes from MYSQL db
*/ */
const allExistingIndexes = await varDatabaseDbHandler({ const allExistingIndexes = await varDatabaseDbHandler({
queryString: `SHOW INDEXES FROM \`${tableName}\``, queryString: `SHOW INDEXES FROM \`${tableName}\``,
database: dbFullName, database: dbFullName,
}); });
/** /**
* @description Check for existing Index in MYSQL db * @description Check for existing Index in MYSQL db
*/ */
try { try {
const existingKeyInDb = allExistingIndexes ? allExistingIndexes.filter((indexObject) => indexObject.Key_name === alias) : null; const existingKeyInDb = allExistingIndexes ? allExistingIndexes.filter((indexObject) => indexObject.Key_name === alias) : null;
if (!existingKeyInDb?.[0]) throw new Error("This Index Does not Exist"); if (!existingKeyInDb?.[0]) throw new Error("This Index Does not Exist");
} catch (error) { } catch (error) {
/** /**
* @description Create new index if determined that it * @description Create new index if determined that it
* doesn't exist in MYSQL db * doesn't exist in MYSQL db
*/ */
await varDatabaseDbHandler({ await varDatabaseDbHandler({
queryString: `CREATE${indexType.match(/fullText/i) ? " FULLTEXT" : ""} INDEX \`${alias}\` ON ${tableName}(${indexTableFields queryString: `CREATE${indexType.match(/fullText/i) ? " FULLTEXT" : ""} INDEX \`${alias}\` ON ${tableName}(${indexTableFields
.map((nm) => nm.value) .map((nm) => nm.value)
.map((nm) => `\`${nm}\``) .map((nm) => `\`${nm}\``)
.join(",")}) COMMENT 'schema_index'`, .join(",")}) COMMENT 'schema_index'`,
database: dbFullName, database: dbFullName,
}); });
} }
} }
} }
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in createDbFromSchema => ", error.message); console.log("Error in createDbFromSchema => ", error.message);
} }
} }
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
module.exports = createDbFromSchema; module.exports = createDbFromSchema;

View File

@ -1,73 +1,73 @@
[ [
{ {
"title": "VARCHAR", "title": "VARCHAR",
"name": "VARCHAR", "name": "VARCHAR",
"value": "0-255", "value": "0-255",
"argument": true, "argument": true,
"description": "Varchar is simply letters and numbers within the range 0 - 255", "description": "Varchar is simply letters and numbers within the range 0 - 255",
"maxValue": 255 "maxValue": 255
}, },
{ {
"title": "TINYINT", "title": "TINYINT",
"name": "TINYINT", "name": "TINYINT",
"value": "0-100", "value": "0-100",
"description": "TINYINT means Integers: 0 to 100", "description": "TINYINT means Integers: 0 to 100",
"maxValue": 127 "maxValue": 127
}, },
{ {
"title": "SMALLINT", "title": "SMALLINT",
"name": "SMALLINT", "name": "SMALLINT",
"value": "0-255", "value": "0-255",
"description": "SMALLINT means Integers: 0 to 240933", "description": "SMALLINT means Integers: 0 to 240933",
"maxValue": 32767 "maxValue": 32767
}, },
{ {
"title": "MEDIUMINT", "title": "MEDIUMINT",
"name": "MEDIUMINT", "name": "MEDIUMINT",
"value": "0-255", "value": "0-255",
"description": "MEDIUMINT means Integers: 0 to 1245568545560", "description": "MEDIUMINT means Integers: 0 to 1245568545560",
"maxValue": 8388607 "maxValue": 8388607
}, },
{ {
"title": "INT", "title": "INT",
"name": "INT", "name": "INT",
"value": "0-255", "value": "0-255",
"description": "INT means Integers: 0 to 12560", "description": "INT means Integers: 0 to 12560",
"maxValue": 2147483647 "maxValue": 2147483647
}, },
{ {
"title": "BIGINT", "title": "BIGINT",
"name": "BIGINT", "name": "BIGINT",
"value": "0-255", "value": "0-255",
"description": "BIGINT means Integers: 0 to 1245569056767568545560", "description": "BIGINT means Integers: 0 to 1245569056767568545560",
"maxValue": 2e63 "maxValue": 2e63
}, },
{ {
"title": "TINYTEXT", "title": "TINYTEXT",
"name": "TINYTEXT", "name": "TINYTEXT",
"value": "0-255", "value": "0-255",
"description": "Text with 255 max characters", "description": "Text with 255 max characters",
"maxValue": 127 "maxValue": 127
}, },
{ {
"title": "TEXT", "title": "TEXT",
"name": "TEXT", "name": "TEXT",
"value": "0-100", "value": "0-100",
"description": "MEDIUMTEXT is just text with max length 16,777,215", "description": "MEDIUMTEXT is just text with max length 16,777,215",
"maxValue": 127 "maxValue": 127
}, },
{ {
"title": "MEDIUMTEXT", "title": "MEDIUMTEXT",
"name": "MEDIUMTEXT", "name": "MEDIUMTEXT",
"value": "0-255", "value": "0-255",
"description": "MEDIUMTEXT is just text with max length 16,777,215", "description": "MEDIUMTEXT is just text with max length 16,777,215",
"maxValue": 127 "maxValue": 127
}, },
{ {
"title": "LONGTEXT", "title": "LONGTEXT",
"name": "LONGTEXT", "name": "LONGTEXT",
"value": "0-255", "value": "0-255",
"description": "LONGTEXT is just text with max length 4,294,967,295", "description": "LONGTEXT is just text with max length 4,294,967,295",
"maxValue": 127 "maxValue": 127
} }
] ]

View File

@ -1,39 +1,39 @@
[ [
{ {
"fieldName": "id", "fieldName": "id",
"dataType": "BIGINT", "dataType": "BIGINT",
"notNullValue": true, "notNullValue": true,
"primaryKey": true, "primaryKey": true,
"autoIncrement": true "autoIncrement": true
}, },
{ {
"fieldName": "date_created", "fieldName": "date_created",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_created_code", "fieldName": "date_created_code",
"dataType": "BIGINT", "dataType": "BIGINT",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_created_timestamp", "fieldName": "date_created_timestamp",
"dataType": "TIMESTAMP", "dataType": "TIMESTAMP",
"defaultValueLiteral": "CURRENT_TIMESTAMP" "defaultValueLiteral": "CURRENT_TIMESTAMP"
}, },
{ {
"fieldName": "date_updated", "fieldName": "date_updated",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_updated_code", "fieldName": "date_updated_code",
"dataType": "BIGINT", "dataType": "BIGINT",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_updated_timestamp", "fieldName": "date_updated_timestamp",
"dataType": "TIMESTAMP", "dataType": "TIMESTAMP",
"defaultValueLiteral": "CURRENT_TIMESTAMP" "defaultValueLiteral": "CURRENT_TIMESTAMP"
} }
] ]

View File

@ -1,17 +1,17 @@
{ {
"fieldName": "string", "fieldName": "string",
"dataType": "BIGINT", "dataType": "BIGINT",
"nullValue": true, "nullValue": true,
"primaryKey": true, "primaryKey": true,
"autoIncrement": true, "autoIncrement": true,
"defaultValue": "CURRENT_TIMESTAMP", "defaultValue": "CURRENT_TIMESTAMP",
"defaultValueLiteral": "CURRENT_TIMESTAMP", "defaultValueLiteral": "CURRENT_TIMESTAMP",
"notNullValue": true, "notNullValue": true,
"foreignKey": { "foreignKey": {
"foreignKeyName": "Name", "foreignKeyName": "Name",
"destinationTableName": "Table Name", "destinationTableName": "Table Name",
"destinationTableColumnName": "Column Name", "destinationTableColumnName": "Column Name",
"cascadeDelete": true, "cascadeDelete": true,
"cascadeUpdate": true "cascadeUpdate": true
} }
} }

View File

@ -1,132 +1,132 @@
{ {
"tableName": "users", "tableName": "users",
"tableFullName": "Users", "tableFullName": "Users",
"fields": [ "fields": [
{ {
"fieldName": "id", "fieldName": "id",
"dataType": "BIGINT", "dataType": "BIGINT",
"notNullValue": true, "notNullValue": true,
"primaryKey": true, "primaryKey": true,
"autoIncrement": true "autoIncrement": true
}, },
{ {
"fieldName": "first_name", "fieldName": "first_name",
"dataType": "VARCHAR(100)", "dataType": "VARCHAR(100)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "last_name", "fieldName": "last_name",
"dataType": "VARCHAR(100)", "dataType": "VARCHAR(100)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "email", "fieldName": "email",
"dataType": "VARCHAR(200)", "dataType": "VARCHAR(200)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "phone", "fieldName": "phone",
"dataType": "VARCHAR(50)" "dataType": "VARCHAR(50)"
}, },
{ {
"fieldName": "user_type", "fieldName": "user_type",
"dataType": "VARCHAR(20)", "dataType": "VARCHAR(20)",
"defaultValue": "default" "defaultValue": "default"
}, },
{ {
"fieldName": "username", "fieldName": "username",
"dataType": "VARCHAR(100)", "dataType": "VARCHAR(100)",
"nullValue": true "nullValue": true
}, },
{ {
"fieldName": "password", "fieldName": "password",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "image", "fieldName": "image",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"defaultValue": "/images/user_images/user-preset.png" "defaultValue": "/images/user_images/user-preset.png"
}, },
{ {
"fieldName": "image_thumbnail", "fieldName": "image_thumbnail",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"defaultValue": "/images/user_images/user-preset-thumbnail.png" "defaultValue": "/images/user_images/user-preset-thumbnail.png"
}, },
{ {
"fieldName": "address", "fieldName": "address",
"dataType": "VARCHAR(255)" "dataType": "VARCHAR(255)"
}, },
{ {
"fieldName": "city", "fieldName": "city",
"dataType": "VARCHAR(50)" "dataType": "VARCHAR(50)"
}, },
{ {
"fieldName": "state", "fieldName": "state",
"dataType": "VARCHAR(50)" "dataType": "VARCHAR(50)"
}, },
{ {
"fieldName": "country", "fieldName": "country",
"dataType": "VARCHAR(50)" "dataType": "VARCHAR(50)"
}, },
{ {
"fieldName": "zip_code", "fieldName": "zip_code",
"dataType": "VARCHAR(50)" "dataType": "VARCHAR(50)"
}, },
{ {
"fieldName": "social_login", "fieldName": "social_login",
"dataType": "TINYINT", "dataType": "TINYINT",
"defaultValue": "0" "defaultValue": "0"
}, },
{ {
"fieldName": "social_platform", "fieldName": "social_platform",
"dataType": "VARCHAR(50)", "dataType": "VARCHAR(50)",
"nullValue": true "nullValue": true
}, },
{ {
"fieldName": "social_id", "fieldName": "social_id",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"nullValue": true "nullValue": true
}, },
{ {
"fieldName": "more_user_data", "fieldName": "more_user_data",
"dataType": "BIGINT", "dataType": "BIGINT",
"defaultValue": "0" "defaultValue": "0"
}, },
{ {
"fieldName": "verification_status", "fieldName": "verification_status",
"dataType": "TINYINT", "dataType": "TINYINT",
"defaultValue": "0" "defaultValue": "0"
}, },
{ {
"fieldName": "date_created", "fieldName": "date_created",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_created_code", "fieldName": "date_created_code",
"dataType": "BIGINT", "dataType": "BIGINT",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_created_timestamp", "fieldName": "date_created_timestamp",
"dataType": "TIMESTAMP", "dataType": "TIMESTAMP",
"defaultValueLiteral": "CURRENT_TIMESTAMP" "defaultValueLiteral": "CURRENT_TIMESTAMP"
}, },
{ {
"fieldName": "date_updated", "fieldName": "date_updated",
"dataType": "VARCHAR(250)", "dataType": "VARCHAR(250)",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_updated_code", "fieldName": "date_updated_code",
"dataType": "BIGINT", "dataType": "BIGINT",
"notNullValue": true "notNullValue": true
}, },
{ {
"fieldName": "date_updated_timestamp", "fieldName": "date_updated_timestamp",
"dataType": "TIMESTAMP", "dataType": "TIMESTAMP",
"defaultValueLiteral": "CURRENT_TIMESTAMP" "defaultValueLiteral": "CURRENT_TIMESTAMP"
} }
] ]
} }

View File

@ -1,54 +1,54 @@
// @ts-check // @ts-check
/** /**
* Convert Camel Joined Text to Camel Spaced Text * Convert Camel Joined Text to Camel Spaced Text
* ============================================================================== * ==============================================================================
* @description this function takes a camel cased text without spaces, and returns * @description this function takes a camel cased text without spaces, and returns
* a camel-case-spaced text * a camel-case-spaced text
* *
* @param {string} text - text string without spaces * @param {string} text - text string without spaces
* *
* @returns {string | null} * @returns {string | null}
*/ */
function camelJoinedtoCamelSpace(text) { function camelJoinedtoCamelSpace(text) {
if (!text?.match(/./)) { if (!text?.match(/./)) {
return ""; return "";
} }
if (text?.match(/ /)) { if (text?.match(/ /)) {
return text; return text;
} }
if (text) { if (text) {
let textArray = text.split(""); let textArray = text.split("");
let capIndexes = []; let capIndexes = [];
for (let i = 0; i < textArray.length; i++) { for (let i = 0; i < textArray.length; i++) {
const char = textArray[i]; const char = textArray[i];
if (i === 0) continue; if (i === 0) continue;
if (char.match(/[A-Z]/)) { if (char.match(/[A-Z]/)) {
capIndexes.push(i); capIndexes.push(i);
} }
} }
let textChunks = [`${textArray[0].toUpperCase()}${text.substring(1, capIndexes[0])}`]; let textChunks = [`${textArray[0].toUpperCase()}${text.substring(1, capIndexes[0])}`];
for (let j = 0; j < capIndexes.length; j++) { for (let j = 0; j < capIndexes.length; j++) {
const capIndex = capIndexes[j]; const capIndex = capIndexes[j];
if (capIndex === 0) continue; if (capIndex === 0) continue;
const startIndex = capIndex + 1; const startIndex = capIndex + 1;
const endIndex = capIndexes[j + 1]; const endIndex = capIndexes[j + 1];
textChunks.push(`${textArray[capIndex].toUpperCase()}${text.substring(startIndex, endIndex)}`); textChunks.push(`${textArray[capIndex].toUpperCase()}${text.substring(startIndex, endIndex)}`);
} }
return textChunks.join(" "); return textChunks.join(" ");
} else { } else {
return null; return null;
} }
} }
module.exports = camelJoinedtoCamelSpace; module.exports = camelJoinedtoCamelSpace;

View File

@ -1,112 +1,112 @@
// @ts-check // @ts-check
const generateColumnDescription = require("./generateColumnDescription"); const generateColumnDescription = require("./generateColumnDescription");
const supplementTable = require("./supplementTable"); const supplementTable = require("./supplementTable");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
module.exports = async function createTable({ dbFullName, tableName, tableInfoArray, varDatabaseDbHandler, dbSchema }) { module.exports = async function createTable({ dbFullName, tableName, tableInfoArray, varDatabaseDbHandler, dbSchema }) {
/** /**
* Format tableInfoArray * Format tableInfoArray
* *
* @description Format tableInfoArray * @description Format tableInfoArray
*/ */
const finalTable = supplementTable({ tableInfoArray: tableInfoArray }); const finalTable = supplementTable({ tableInfoArray: tableInfoArray });
/** /**
* Grab Schema * Grab Schema
* *
* @description Grab Schema * @description Grab Schema
*/ */
const createTableQueryArray = []; const createTableQueryArray = [];
createTableQueryArray.push(`CREATE TABLE IF NOT EXISTS \`${tableName}\` (`); createTableQueryArray.push(`CREATE TABLE IF NOT EXISTS \`${tableName}\` (`);
//////////////////////////////////////// ////////////////////////////////////////
let primaryKeySet = false; let primaryKeySet = false;
let foreignKeys = []; let foreignKeys = [];
//////////////////////////////////////// ////////////////////////////////////////
for (let i = 0; i < finalTable.length; i++) { for (let i = 0; i < finalTable.length; i++) {
const column = finalTable[i]; const column = finalTable[i];
const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, foreignKey, updatedField } = column; const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, foreignKey, updatedField } = column;
if (foreignKey) { if (foreignKey) {
foreignKeys.push({ foreignKeys.push({
fieldName: fieldName, fieldName: fieldName,
...foreignKey, ...foreignKey,
}); });
} }
let { fieldEntryText, newPrimaryKeySet } = generateColumnDescription({ columnData: column, primaryKeySet: primaryKeySet }); let { fieldEntryText, newPrimaryKeySet } = generateColumnDescription({ columnData: column, primaryKeySet: primaryKeySet });
primaryKeySet = newPrimaryKeySet; primaryKeySet = newPrimaryKeySet;
//////////////////////////////////////// ////////////////////////////////////////
if (fieldName?.match(/updated_timestamp/i)) { if (fieldName?.match(/updated_timestamp/i)) {
fieldEntryText += " ON UPDATE CURRENT_TIMESTAMP"; fieldEntryText += " ON UPDATE CURRENT_TIMESTAMP";
} }
//////////////////////////////////////// ////////////////////////////////////////
const comma = (() => { const comma = (() => {
if (foreignKeys[0]) return ","; if (foreignKeys[0]) return ",";
if (i === finalTable.length - 1) return ""; if (i === finalTable.length - 1) return "";
return ","; return ",";
})(); })();
createTableQueryArray.push(" " + fieldEntryText + comma); createTableQueryArray.push(" " + fieldEntryText + comma);
//////////////////////////////////////// ////////////////////////////////////////
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (foreignKeys[0]) { if (foreignKeys[0]) {
foreignKeys.forEach((foreighKey, index, array) => { foreignKeys.forEach((foreighKey, index, array) => {
const { fieldName, destinationTableName, destinationTableColumnName, cascadeDelete, cascadeUpdate, foreignKeyName } = foreighKey; const { fieldName, destinationTableName, destinationTableColumnName, cascadeDelete, cascadeUpdate, foreignKeyName } = foreighKey;
const comma = (() => { const comma = (() => {
if (index === foreignKeys.length - 1) return ""; if (index === foreignKeys.length - 1) return "";
return ","; return ",";
})(); })();
createTableQueryArray.push(` CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (\`${fieldName}\`) REFERENCES \`${destinationTableName}\`(${destinationTableColumnName})${cascadeDelete ? " ON DELETE CASCADE" : ""}${cascadeUpdate ? " ON UPDATE CASCADE" : ""}${comma}`); createTableQueryArray.push(` CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (\`${fieldName}\`) REFERENCES \`${destinationTableName}\`(${destinationTableColumnName})${cascadeDelete ? " ON DELETE CASCADE" : ""}${cascadeUpdate ? " ON UPDATE CASCADE" : ""}${comma}`);
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
createTableQueryArray.push(`) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;`); createTableQueryArray.push(`) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;`);
const createTableQuery = createTableQueryArray.join("\n"); const createTableQuery = createTableQueryArray.join("\n");
//////////////////////////////////////// ////////////////////////////////////////
const newTable = await varDatabaseDbHandler({ const newTable = await varDatabaseDbHandler({
queryString: createTableQuery, queryString: createTableQuery,
database: dbFullName, database: dbFullName,
}); });
return newTable; return newTable;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
}; };
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */

View File

@ -1,157 +1,173 @@
/** # MODULE TRACE /** # MODULE TRACE
====================================================================== ======================================================================
* Detected 8 files that call this module. The files are listed below: * Detected 8 files that call this module. The files are listed below:
====================================================================== ======================================================================
* `require` Statement Found in [noDatabaseDbHandler.js](d:\GitHub\dsql\engine\engine\utils\noDatabaseDbHandler.js) * `require` Statement Found in [noDatabaseDbHandler.js](d:\GitHub\dsql\engine\engine\utils\noDatabaseDbHandler.js)
* `require` Statement Found in [varDatabaseDbHandler.js](d:\GitHub\dsql\engine\engine\utils\varDatabaseDbHandler.js) * `require` Statement Found in [varDatabaseDbHandler.js](d:\GitHub\dsql\engine\engine\utils\varDatabaseDbHandler.js)
* `require` Statement Found in [addDbEntry.js](d:\GitHub\dsql\engine\query\utils\addDbEntry.js) * `require` Statement Found in [addDbEntry.js](d:\GitHub\dsql\engine\query\utils\addDbEntry.js)
* `require` Statement Found in [deleteDbEntry.js](d:\GitHub\dsql\engine\query\utils\deleteDbEntry.js) * `require` Statement Found in [deleteDbEntry.js](d:\GitHub\dsql\engine\query\utils\deleteDbEntry.js)
* `require` Statement Found in [runQuery.js](d:\GitHub\dsql\engine\query\utils\runQuery.js) * `require` Statement Found in [runQuery.js](d:\GitHub\dsql\engine\query\utils\runQuery.js)
* `require` Statement Found in [updateDbEntry.js](d:\GitHub\dsql\engine\query\utils\updateDbEntry.js) * `require` Statement Found in [updateDbEntry.js](d:\GitHub\dsql\engine\query\utils\updateDbEntry.js)
* `require` Statement Found in [githubLogin.js](d:\GitHub\dsql\engine\user\social\utils\githubLogin.js) * `require` Statement Found in [githubLogin.js](d:\GitHub\dsql\engine\user\social\utils\githubLogin.js)
* `require` Statement Found in [googleLogin.js](d:\GitHub\dsql\engine\user\social\utils\googleLogin.js) * `require` Statement Found in [googleLogin.js](d:\GitHub\dsql\engine\user\social\utils\googleLogin.js)
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check // @ts-check
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const fs = require("fs"); const fs = require("fs");
const mysql = require("mysql"); const mysql = require("mysql");
const parseDbResults = require("./parseDbResults"); const parseDbResults = require("./parseDbResults");
const connection = mysql.createConnection({ const connection = mysql.createConnection({
host: process.env.DSQL_HOST, host: process.env.DSQL_HOST,
user: process.env.DSQL_USER, user: process.env.DSQL_USER,
database: process.env.DSQL_DB_NAME, database: process.env.DSQL_DB_NAME,
password: process.env.DSQL_PASS, password: process.env.DSQL_PASS,
charset: "utf8mb4", charset: "utf8mb4",
port: process.env.DSQL_PORT?.match(/.../) ? parseInt(process.env.DSQL_PORT) : undefined, port: process.env.DSQL_PORT?.match(/.../)
timeout: 5000, ? parseInt(process.env.DSQL_PORT)
}); : undefined,
timeout: 5000,
////////////////////////////////////////////////////////////////////////////////// });
//////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
/** //////////////////////////////////////////////////////////////////////////////////
* Main DB Handler Function
* ============================================================================== /**
* @async * Main DB Handler Function
* @param {object} params - Single Param object containing params * ==============================================================================
* @param {string} params.query - Query String * @async
* @param {(string | number)[]} [params.values] - Values * @param {object} params - Single Param object containing params
* @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Database Schema * @param {string} params.query - Query String
* @param {string} [params.database] - Target Database * @param {(string | number)[]} [params.values] - Values
* @param {string} [params.tableName] - Target Table Name * @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Database Schema
* * @param {string} [params.database] - Target Database
* @returns {Promise<*>} * @param {string} [params.tableName] - Target Table Name
*/ *
module.exports = async function dbHandler({ query, values, database, dbSchema, tableName }) { * @returns {Promise<*>}
/** */
* Declare variables module.exports = async function dbHandler({
* query,
* @description Declare "results" variable values,
*/ database,
let changeDbError; dbSchema,
tableName,
if (database) { }) {
connection.changeUser({ database: database }, (error) => { /**
if (error) { * Declare variables
console.log("DB handler error in switching database:", error.message); *
changeDbError = error.message; * @description Declare "results" variable
} */
}); let changeDbError;
}
console.log(connection.config);
if (changeDbError) {
return { error: changeDbError }; if (database) {
} connection.changeUser({ database: database }, (error) => {
if (error) {
/** console.log(
* Declare variables "DB handler error in switching database:",
* error.message
* @description Declare "results" variable );
*/ changeDbError = error.message;
let results; }
});
/** }
* Fetch from db
* if (changeDbError) {
* @description Fetch data from db if no cache return { error: changeDbError };
*/ }
try {
results = await new Promise((resolve, reject) => { /**
if (values?.[0]) { * Declare variables
connection.query(query, values, (error, results, fields) => { *
if (error) { * @description Declare "results" variable
console.log("DB handler error with values array:", error.message); */
console.log("SQL:", error.sql); let results;
console.log("State:", error.sqlState, error.sqlMessage);
/**
resolve({ * Fetch from db
error: error.message, *
}); * @description Fetch data from db if no cache
} else { */
resolve(JSON.parse(JSON.stringify(results))); try {
} results = await new Promise((resolve, reject) => {
if (values?.[0]) {
// setTimeout(() => { connection.query(query, values, (error, results, fields) => {
// endConnection(connection); if (error) {
// }, 500); console.log(
}); "DB handler error with values array:",
} else { error.message
connection.query(query, (error, results, fields) => { );
if (error) { console.log("SQL:", error.sql);
console.log("DB handler error:", error.message); console.log("State:", error.sqlState, error.sqlMessage);
console.log("SQL:", error.sql);
console.log("State:", error.sqlState, error.sqlMessage); resolve({
error: error.message,
resolve({ });
error: error.message, } else {
}); resolve(JSON.parse(JSON.stringify(results)));
} else { }
resolve(JSON.parse(JSON.stringify(results)));
} // setTimeout(() => {
// setTimeout(() => { // endConnection(connection);
// endConnection(connection); // }, 500);
// }, 500); });
}); } else {
} connection.query(query, (error, results, fields) => {
}); if (error) {
console.log("DB handler error:", error.message);
//////////////////////////////////////// console.log("SQL:", error.sql);
//////////////////////////////////////// console.log("State:", error.sqlState, error.sqlMessage);
////////////////////////////////////////
} catch (/** @type {*} */ error) { resolve({
console.log("DB handler error:", error.message); error: error.message,
});
results = null; } else {
} resolve(JSON.parse(JSON.stringify(results)));
}
/** // setTimeout(() => {
* Return results // endConnection(connection);
* // }, 500);
* @description Return results add to cache if "req" param is passed });
*/ }
// if (results && dbSchema && tableName) { });
// const tableSchema = dbSchema.tables.find((table) => table.tableName === tableName);
// const parsedResults = parseDbResults({ ////////////////////////////////////////
// unparsedResults: results, ////////////////////////////////////////
// tableSchema: tableSchema, ////////////////////////////////////////
// }); } catch (/** @type {*} */ error) {
console.log("DB handler error:", error.message);
// return parsedResults;
// } else results = null;
if (results) { }
return results;
} else { /**
console.log("DSQL DB handler no results received for Query =>", query); * Return results
return null; *
} * @description Return results add to cache if "req" param is passed
}; */
// if (results && dbSchema && tableName) {
// const tableSchema = dbSchema.tables.find((table) => table.tableName === tableName);
// const parsedResults = parseDbResults({
// unparsedResults: results,
// tableSchema: tableSchema,
// });
// return parsedResults;
// } else
if (results) {
return results;
} else {
console.log("DSQL DB handler no results received for Query =>", query);
return null;
}
};

View File

@ -1,13 +1,13 @@
/** /**
* Regular expression to match default fields * Regular expression to match default fields
* *
* @description Regular expression to match default fields * @description Regular expression to match default fields
* @type {RegExp} * @type {RegExp}
*/ */
const defaultFieldsRegexp = /^id$|^date_created$|^date_created_code$|^date_created_timestamp$|^date_updated$|^date_updated_code$|^date_updated_timestamp$/; const defaultFieldsRegexp = /^id$|^date_created$|^date_created_code$|^date_created_timestamp$|^date_updated$|^date_updated_code$|^date_updated_timestamp$/;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = defaultFieldsRegexp; module.exports = defaultFieldsRegexp;

View File

@ -1,16 +1,16 @@
// @ts-check // @ts-check
const mysql = require("mysql"); const mysql = require("mysql");
/** /**
* @param {mysql.Connection} connection - the active MYSQL connection * @param {mysql.Connection} connection - the active MYSQL connection
*/ */
function endConnection(connection) { function endConnection(connection) {
if (connection.state !== "disconnected") { if (connection.state !== "disconnected") {
connection.end((err) => { connection.end((err) => {
console.log(err?.message); console.log(err?.message);
}); });
} }
} }
module.exports = endConnection; module.exports = endConnection;

View File

@ -1,68 +1,68 @@
// @ts-check // @ts-check
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* Generate SQL text for Field * Generate SQL text for Field
* ============================================================================== * ==============================================================================
* @param {object} params - Single object params * @param {object} params - Single object params
* @param {import("../../../types/database-schema.td").DSQL_FieldSchemaType} params.columnData - Field object * @param {import("../../../types/database-schema.td").DSQL_FieldSchemaType} params.columnData - Field object
* @param {boolean} [params.primaryKeySet] - Table Name(slug) * @param {boolean} [params.primaryKeySet] - Table Name(slug)
* *
* @returns {{fieldEntryText: string, newPrimaryKeySet: boolean}} * @returns {{fieldEntryText: string, newPrimaryKeySet: boolean}}
*/ */
module.exports = function generateColumnDescription({ columnData, primaryKeySet }) { module.exports = function generateColumnDescription({ columnData, primaryKeySet }) {
/** /**
* Format tableInfoArray * Format tableInfoArray
* *
* @description Format tableInfoArray * @description Format tableInfoArray
*/ */
const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, notNullValue } = columnData; const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, notNullValue } = columnData;
let fieldEntryText = ""; let fieldEntryText = "";
fieldEntryText += `\`${fieldName}\` ${dataType}`; fieldEntryText += `\`${fieldName}\` ${dataType}`;
//////////////////////////////////////// ////////////////////////////////////////
if (nullValue) { if (nullValue) {
fieldEntryText += " DEFAULT NULL"; fieldEntryText += " DEFAULT NULL";
} else if (defaultValueLiteral) { } else if (defaultValueLiteral) {
fieldEntryText += ` DEFAULT ${defaultValueLiteral}`; fieldEntryText += ` DEFAULT ${defaultValueLiteral}`;
} else if (defaultValue) { } else if (defaultValue) {
fieldEntryText += ` DEFAULT '${defaultValue}'`; fieldEntryText += ` DEFAULT '${defaultValue}'`;
} else if (notNullValue) { } else if (notNullValue) {
fieldEntryText += ` NOT NULL`; fieldEntryText += ` NOT NULL`;
} }
//////////////////////////////////////// ////////////////////////////////////////
if (primaryKey && !primaryKeySet) { if (primaryKey && !primaryKeySet) {
fieldEntryText += " PRIMARY KEY"; fieldEntryText += " PRIMARY KEY";
primaryKeySet = true; primaryKeySet = true;
} }
//////////////////////////////////////// ////////////////////////////////////////
if (autoIncrement) { if (autoIncrement) {
fieldEntryText += " AUTO_INCREMENT"; fieldEntryText += " AUTO_INCREMENT";
primaryKeySet = true; primaryKeySet = true;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return { fieldEntryText, newPrimaryKeySet: primaryKeySet || false }; return { fieldEntryText, newPrimaryKeySet: primaryKeySet || false };
}; };
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */

View File

@ -1,89 +1,89 @@
// @ts-check // @ts-check
const fs = require("fs"); const fs = require("fs");
const dbHandler = require("./dbHandler"); const dbHandler = require("./dbHandler");
const mysql = require("mysql"); const mysql = require("mysql");
const endConnection = require("./endConnection"); const endConnection = require("./endConnection");
const connection = mysql.createConnection({ const connection = mysql.createConnection({
host: process.env.DSQL_HOST, host: process.env.DSQL_HOST,
user: process.env.DSQL_USER, user: process.env.DSQL_USER,
password: process.env.DSQL_PASS, password: process.env.DSQL_PASS,
charset: "utf8mb4", charset: "utf8mb4",
port: process.env.DSQL_PORT?.match(/.../) ? parseInt(process.env.DSQL_PORT) : undefined, port: process.env.DSQL_PORT?.match(/.../) ? parseInt(process.env.DSQL_PORT) : undefined,
timeout: 5000, timeout: 5000,
}); });
/** /**
* Create database from Schema Function * Create database from Schema Function
* ============================================================================== * ==============================================================================
* @param {object} params - Single Param object containing params * @param {object} params - Single Param object containing params
* @param {string} params.query - Query String * @param {string} params.query - Query String
* @param {string[]} [params.values] - Values * @param {string[]} [params.values] - Values
* *
* @returns {Promise<object[] | null>} * @returns {Promise<object[] | null>}
*/ */
module.exports = async function noDatabaseDbHandler({ query, values }) { module.exports = async function noDatabaseDbHandler({ query, values }) {
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
let results; let results;
/** /**
* Fetch from db * Fetch from db
* *
* @description Fetch data from db if no cache * @description Fetch data from db if no cache
*/ */
try { try {
/** ********************* Run Query */ /** ********************* Run Query */
results = await new Promise((resolve, reject) => { results = await new Promise((resolve, reject) => {
if (values) { if (values) {
connection.query(query, values, (error, results, fields) => { connection.query(query, values, (error, results, fields) => {
if (error) { if (error) {
console.log("NO-DB handler error:", error.message); console.log("NO-DB handler error:", error.message);
resolve({ resolve({
error: error.message, error: error.message,
}); });
} else { } else {
resolve(JSON.parse(JSON.stringify(results))); resolve(JSON.parse(JSON.stringify(results)));
} }
// setTimeout(() => { // setTimeout(() => {
// endConnection(connection); // endConnection(connection);
// }, 500); // }, 500);
}); });
} else { } else {
connection.query(query, (error, results, fields) => { connection.query(query, (error, results, fields) => {
if (error) { if (error) {
console.log("NO-DB handler error:", error.message); console.log("NO-DB handler error:", error.message);
resolve({ resolve({
error: error.message, error: error.message,
}); });
} else { } else {
resolve(JSON.parse(JSON.stringify(results))); resolve(JSON.parse(JSON.stringify(results)));
} }
// setTimeout(() => { // setTimeout(() => {
// endConnection(connection); // endConnection(connection);
// }, 500); // }, 500);
}); });
} }
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("ERROR in noDatabaseDbHandler =>", error.message); console.log("ERROR in noDatabaseDbHandler =>", error.message);
} }
/** /**
* Return results * Return results
* *
* @description Return results add to cache if "req" param is passed * @description Return results add to cache if "req" param is passed
*/ */
if (results) { if (results) {
return results; return results;
} else { } else {
return null; return null;
} }
}; };

View File

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

View File

@ -1,16 +1,16 @@
// @ts-check // @ts-check
module.exports = function slugToCamelTitle(text) { module.exports = function slugToCamelTitle(text) {
if (text) { if (text) {
let addArray = text.split("-").filter((item) => item !== ""); let addArray = text.split("-").filter((item) => item !== "");
let camelArray = addArray.map((item) => { let camelArray = addArray.map((item) => {
return item.substr(0, 1).toUpperCase() + item.substr(1).toLowerCase(); return item.substr(0, 1).toUpperCase() + item.substr(1).toLowerCase();
}); });
let parsedAddress = camelArray.join(" "); let parsedAddress = camelArray.join(" ");
return parsedAddress; return parsedAddress;
} else { } else {
return null; return null;
} }
}; };

View File

@ -1,48 +1,48 @@
// @ts-check // @ts-check
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
module.exports = function supplementTable({ tableInfoArray }) { module.exports = function supplementTable({ tableInfoArray }) {
/** /**
* Format tableInfoArray * Format tableInfoArray
* *
* @description Format tableInfoArray * @description Format tableInfoArray
*/ */
let finalTableArray = tableInfoArray; let finalTableArray = tableInfoArray;
const defaultFields = require("../data/defaultFields.json"); const defaultFields = require("../data/defaultFields.json");
//////////////////////////////////////// ////////////////////////////////////////
let primaryKeyExists = finalTableArray.filter((_field) => _field.primaryKey); let primaryKeyExists = finalTableArray.filter((_field) => _field.primaryKey);
//////////////////////////////////////// ////////////////////////////////////////
defaultFields.forEach((field) => { defaultFields.forEach((field) => {
let fieldExists = finalTableArray.filter((_field) => _field.fieldName === field.fieldName); let fieldExists = finalTableArray.filter((_field) => _field.fieldName === field.fieldName);
if (fieldExists && fieldExists[0]) { if (fieldExists && fieldExists[0]) {
return; return;
} else if (field.fieldName === "id" && !primaryKeyExists[0]) { } else if (field.fieldName === "id" && !primaryKeyExists[0]) {
finalTableArray.unshift(field); finalTableArray.unshift(field);
} else { } else {
finalTableArray.push(field); finalTableArray.push(field);
} }
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return finalTableArray; return finalTableArray;
}; };
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */

View File

@ -1,457 +1,457 @@
// @ts-check // @ts-check
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///////////////////////// - Update Table Function - //////////////////////////// ///////////////////////// - Update Table Function - ////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const defaultFieldsRegexp = /^id$|^date_created$|^date_created_code$|^date_created_timestamp$|^date_updated$|^date_updated_code$|^date_updated_timestamp$/; const defaultFieldsRegexp = /^id$|^date_created$|^date_created_code$|^date_created_timestamp$|^date_updated$|^date_updated_code$|^date_updated_timestamp$/;
const generateColumnDescription = require("./generateColumnDescription"); const generateColumnDescription = require("./generateColumnDescription");
const varDatabaseDbHandler = require("./varDatabaseDbHandler"); const varDatabaseDbHandler = require("./varDatabaseDbHandler");
const schemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const schemaPath = path.resolve(process.cwd(), "dsql.schema.json");
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* Update table function * Update table function
* ============================================================================== * ==============================================================================
* @param {object} params - Single object params * @param {object} params - Single object params
* @param {string} params.dbFullName - Database full name => "datasquirel_user_4394_db_name" * @param {string} params.dbFullName - Database full name => "datasquirel_user_4394_db_name"
* @param {string} params.tableName - Table Name(slug) * @param {string} params.tableName - Table Name(slug)
* @param {import("../../../types/database-schema.td").DSQL_FieldSchemaType[]} params.tableInfoArray - Table Info Array * @param {import("../../../types/database-schema.td").DSQL_FieldSchemaType[]} params.tableInfoArray - Table Info Array
* @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType[]} params.dbSchema - Single post * @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType[]} params.dbSchema - Single post
* @param {import("../../../types/database-schema.td").DSQL_IndexSchemaType[]} [params.tableIndexes] - Table Indexes * @param {import("../../../types/database-schema.td").DSQL_IndexSchemaType[]} [params.tableIndexes] - Table Indexes
* @param {boolean} [params.clone] - Is this a newly cloned table? * @param {boolean} [params.clone] - Is this a newly cloned table?
* @param {number} [params.tableIndex] - The number index of the table in the dbSchema array * @param {number} [params.tableIndex] - The number index of the table in the dbSchema array
* *
* @returns {Promise<string|object[]|null>} * @returns {Promise<string|object[]|null>}
*/ */
module.exports = async function updateTable({ dbFullName, tableName, tableInfoArray, dbSchema, tableIndexes, clone, tableIndex }) { module.exports = async function updateTable({ dbFullName, tableName, tableInfoArray, dbSchema, tableIndexes, clone, tableIndex }) {
/** /**
* Initialize * Initialize
* ========================================== * ==========================================
* @description Initial setup * @description Initial setup
*/ */
/** /**
* @description Initialize table info array. This value will be * @description Initialize table info array. This value will be
* changing depending on if a field is renamed or not. * changing depending on if a field is renamed or not.
*/ */
let upToDateTableFieldsArray = tableInfoArray; let upToDateTableFieldsArray = tableInfoArray;
/** /**
* Handle Table updates * Handle Table updates
* *
* @description Try to undate table, catch error if anything goes wrong * @description Try to undate table, catch error if anything goes wrong
*/ */
try { try {
/** /**
* @type {string[]} * @type {string[]}
* @description Table update query string array * @description Table update query string array
*/ */
const updateTableQueryArray = []; const updateTableQueryArray = [];
/** /**
* @type {string[]} * @type {string[]}
* @description Constriants query string array * @description Constriants query string array
*/ */
const constraintsQueryArray = []; const constraintsQueryArray = [];
/** /**
* @description Push the query initial value * @description Push the query initial value
*/ */
updateTableQueryArray.push(`ALTER TABLE \`${tableName}\``); updateTableQueryArray.push(`ALTER TABLE \`${tableName}\``);
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @type {*} * @type {*}
* @description All indexes from MYSQL db * @description All indexes from MYSQL db
*/ */
const allExistingIndexes = await varDatabaseDbHandler({ const allExistingIndexes = await varDatabaseDbHandler({
queryString: `SHOW INDEXES FROM \`${tableName}\``, queryString: `SHOW INDEXES FROM \`${tableName}\``,
database: dbFullName, database: dbFullName,
}); });
/** /**
* @type {*} * @type {*}
* @description All columns from MYSQL db * @description All columns from MYSQL db
*/ */
const allExistingColumns = await varDatabaseDbHandler({ const allExistingColumns = await varDatabaseDbHandler({
queryString: `SHOW COLUMNS FROM \`${tableName}\``, queryString: `SHOW COLUMNS FROM \`${tableName}\``,
database: dbFullName, database: dbFullName,
}); });
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @type {string[]} * @type {string[]}
* @description Updated column names Array * @description Updated column names Array
*/ */
const updatedColumnsArray = []; const updatedColumnsArray = [];
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Iterate through every existing column * @description Iterate through every existing column
*/ */
if (allExistingColumns) if (allExistingColumns)
for (let e = 0; e < allExistingColumns.length; e++) { for (let e = 0; e < allExistingColumns.length; e++) {
const { Field } = allExistingColumns[e]; const { Field } = allExistingColumns[e];
if (Field.match(defaultFieldsRegexp)) continue; if (Field.match(defaultFieldsRegexp)) continue;
/** /**
* @description This finds out whether the fieldName corresponds with the MSQL Field name * @description This finds out whether the fieldName corresponds with the MSQL Field name
* if the fildName doesn't match any MYSQL Field name, the field is deleted. * if the fildName doesn't match any MYSQL Field name, the field is deleted.
*/ */
let existingEntry = upToDateTableFieldsArray.filter((column) => column.fieldName === Field || column.originName === Field); let existingEntry = upToDateTableFieldsArray.filter((column) => column.fieldName === Field || column.originName === Field);
if (existingEntry && existingEntry[0]) { if (existingEntry && existingEntry[0]) {
/** /**
* @description Check if Field name has been updated * @description Check if Field name has been updated
*/ */
if (existingEntry[0].updatedField) { if (existingEntry[0].updatedField) {
updatedColumnsArray.push(existingEntry[0].fieldName); updatedColumnsArray.push(existingEntry[0].fieldName);
const renameColumn = await varDatabaseDbHandler({ const renameColumn = await varDatabaseDbHandler({
queryString: `ALTER TABLE ${tableName} RENAME COLUMN \`${existingEntry[0].originName}\` TO \`${existingEntry[0].fieldName}\``, queryString: `ALTER TABLE ${tableName} RENAME COLUMN \`${existingEntry[0].originName}\` TO \`${existingEntry[0].fieldName}\``,
database: dbFullName, database: dbFullName,
}); });
console.log(`Column Renamed from "${existingEntry[0].originName}" to "${existingEntry[0].fieldName}"`); console.log(`Column Renamed from "${existingEntry[0].originName}" to "${existingEntry[0].fieldName}"`);
/** /**
* Update Db Schema * Update Db Schema
* =================================================== * ===================================================
* @description Update Db Schema after renaming column * @description Update Db Schema after renaming column
*/ */
try { try {
const userSchemaData = dbSchema; const userSchemaData = dbSchema;
const targetDbIndex = userSchemaData.findIndex((db) => db.dbFullName === dbFullName); const targetDbIndex = userSchemaData.findIndex((db) => db.dbFullName === dbFullName);
const targetTableIndex = userSchemaData[targetDbIndex].tables.findIndex((table) => table.tableName === tableName); const targetTableIndex = userSchemaData[targetDbIndex].tables.findIndex((table) => table.tableName === tableName);
const targetFieldIndex = userSchemaData[targetDbIndex].tables[targetTableIndex].fields.findIndex((field) => field.fieldName === existingEntry[0].fieldName); const targetFieldIndex = userSchemaData[targetDbIndex].tables[targetTableIndex].fields.findIndex((field) => field.fieldName === existingEntry[0].fieldName);
delete userSchemaData[targetDbIndex].tables[targetTableIndex].fields[targetFieldIndex]["originName"]; delete userSchemaData[targetDbIndex].tables[targetTableIndex].fields[targetFieldIndex]["originName"];
delete userSchemaData[targetDbIndex].tables[targetTableIndex].fields[targetFieldIndex]["updatedField"]; delete userSchemaData[targetDbIndex].tables[targetTableIndex].fields[targetFieldIndex]["updatedField"];
/** /**
* @description Set New Table Fields Array * @description Set New Table Fields Array
*/ */
upToDateTableFieldsArray = userSchemaData[targetDbIndex].tables[targetTableIndex].fields; upToDateTableFieldsArray = userSchemaData[targetDbIndex].tables[targetTableIndex].fields;
fs.writeFileSync(schemaPath, JSON.stringify(userSchemaData), "utf8"); fs.writeFileSync(schemaPath, JSON.stringify(userSchemaData), "utf8");
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in updating Table =>", error.message); console.log("Error in updating Table =>", error.message);
} }
//////////////////////////////////////// ////////////////////////////////////////
} }
//////////////////////////////////////// ////////////////////////////////////////
continue; continue;
//////////////////////////////////////// ////////////////////////////////////////
} else { } else {
// console.log("Column Deleted =>", Field); // console.log("Column Deleted =>", Field);
await varDatabaseDbHandler({ await varDatabaseDbHandler({
queryString: `ALTER TABLE ${tableName} DROP COLUMN \`${Field}\``, queryString: `ALTER TABLE ${tableName} DROP COLUMN \`${Field}\``,
database: dbFullName, database: dbFullName,
}); });
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Handle MYSQL Table Indexes * Handle MYSQL Table Indexes
* =================================================== * ===================================================
* @description Iterate through each table index(if available) * @description Iterate through each table index(if available)
* and perform operations * and perform operations
*/ */
if (allExistingIndexes) if (allExistingIndexes)
for (let f = 0; f < allExistingIndexes.length; f++) { for (let f = 0; f < allExistingIndexes.length; f++) {
const { Key_name, Index_comment } = allExistingIndexes[f]; const { Key_name, Index_comment } = allExistingIndexes[f];
/** /**
* @description Check if this index was specifically created * @description Check if this index was specifically created
* by datasquirel * by datasquirel
*/ */
if (Index_comment?.match(/schema_index/)) { if (Index_comment?.match(/schema_index/)) {
try { try {
const existingKeyInSchema = tableIndexes ? tableIndexes.filter((indexObject) => indexObject.alias === Key_name) : null; const existingKeyInSchema = tableIndexes ? tableIndexes.filter((indexObject) => indexObject.alias === Key_name) : null;
if (!existingKeyInSchema?.[0]) throw new Error(`This Index(${Key_name}) Has been Deleted!`); if (!existingKeyInSchema?.[0]) throw new Error(`This Index(${Key_name}) Has been Deleted!`);
} catch (error) { } catch (error) {
/** /**
* @description Drop Index: This happens when the MYSQL index is not * @description Drop Index: This happens when the MYSQL index is not
* present in the datasquirel DB schema * present in the datasquirel DB schema
*/ */
await varDatabaseDbHandler({ await varDatabaseDbHandler({
queryString: `ALTER TABLE ${tableName} DROP INDEX \`${Key_name}\``, queryString: `ALTER TABLE ${tableName} DROP INDEX \`${Key_name}\``,
database: dbFullName, database: dbFullName,
}); });
} }
} }
} }
/** /**
* Handle DATASQUIREL Table Indexes * Handle DATASQUIREL Table Indexes
* =================================================== * ===================================================
* @description Iterate through each datasquirel schema * @description Iterate through each datasquirel schema
* table index(if available), and perform operations * table index(if available), and perform operations
*/ */
if (tableIndexes && tableIndexes[0]) { if (tableIndexes && tableIndexes[0]) {
for (let g = 0; g < tableIndexes.length; g++) { for (let g = 0; g < tableIndexes.length; g++) {
const { indexType, indexName, indexTableFields, alias } = tableIndexes[g]; const { indexType, indexName, indexTableFields, alias } = tableIndexes[g];
if (!alias?.match(/./)) continue; if (!alias?.match(/./)) continue;
/** /**
* @description Check for existing Index in MYSQL db * @description Check for existing Index in MYSQL db
*/ */
try { try {
const existingKeyInDb = allExistingIndexes?.filter((indexObject) => indexObject.Key_name === alias); const existingKeyInDb = allExistingIndexes?.filter((indexObject) => indexObject.Key_name === alias);
if (!existingKeyInDb?.[0]) throw new Error("This Index Does not Exist"); if (!existingKeyInDb?.[0]) throw new Error("This Index Does not Exist");
} catch (error) { } catch (error) {
/** /**
* @description Create new index if determined that it * @description Create new index if determined that it
* doesn't exist in MYSQL db * doesn't exist in MYSQL db
*/ */
await varDatabaseDbHandler({ await varDatabaseDbHandler({
queryString: `CREATE${indexType.match(/fullText/i) ? " FULLTEXT" : ""} INDEX \`${alias}\` ON ${tableName}(${indexTableFields queryString: `CREATE${indexType.match(/fullText/i) ? " FULLTEXT" : ""} INDEX \`${alias}\` ON ${tableName}(${indexTableFields
.map((nm) => nm.value) .map((nm) => nm.value)
.map((nm) => `\`${nm}\``) .map((nm) => `\`${nm}\``)
.join(",")}) COMMENT 'schema_index'`, .join(",")}) COMMENT 'schema_index'`,
database: dbFullName, database: dbFullName,
}); });
} }
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Handle MYSQL Foreign Keys * Handle MYSQL Foreign Keys
* =================================================== * ===================================================
* @description Iterate through each datasquirel schema * @description Iterate through each datasquirel schema
* table index(if available), and perform operations * table index(if available), and perform operations
*/ */
/** /**
* @description All MSQL Foreign Keys * @description All MSQL Foreign Keys
* @type {*} * @type {*}
*/ */
const allForeignKeys = await varDatabaseDbHandler({ const allForeignKeys = await varDatabaseDbHandler({
queryString: `SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = '${dbFullName}' AND TABLE_NAME='${tableName}' AND CONSTRAINT_TYPE='FOREIGN KEY'`, queryString: `SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = '${dbFullName}' AND TABLE_NAME='${tableName}' AND CONSTRAINT_TYPE='FOREIGN KEY'`,
database: dbFullName, database: dbFullName,
}); });
if (allForeignKeys) if (allForeignKeys)
for (let c = 0; c < allForeignKeys.length; c++) { for (let c = 0; c < allForeignKeys.length; c++) {
const { CONSTRAINT_NAME } = allForeignKeys[c]; const { CONSTRAINT_NAME } = allForeignKeys[c];
/** /**
* @description Skip if Key is the PRIMARY Key * @description Skip if Key is the PRIMARY Key
*/ */
if (CONSTRAINT_NAME.match(/PRIMARY/)) continue; if (CONSTRAINT_NAME.match(/PRIMARY/)) continue;
/** /**
* @description Drop all foreign Keys to avoid MYSQL errors when adding/updating * @description Drop all foreign Keys to avoid MYSQL errors when adding/updating
* Foreign keys * Foreign keys
*/ */
const dropForeignKey = await varDatabaseDbHandler({ const dropForeignKey = await varDatabaseDbHandler({
queryString: `ALTER TABLE ${tableName} DROP FOREIGN KEY \`${CONSTRAINT_NAME}\``, queryString: `ALTER TABLE ${tableName} DROP FOREIGN KEY \`${CONSTRAINT_NAME}\``,
database: dbFullName, database: dbFullName,
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Handle DATASQUIREL schema fields for current table * Handle DATASQUIREL schema fields for current table
* =================================================== * ===================================================
* @description Iterate through each field object and * @description Iterate through each field object and
* perform operations * perform operations
*/ */
for (let i = 0; i < upToDateTableFieldsArray.length; i++) { for (let i = 0; i < upToDateTableFieldsArray.length; i++) {
const column = upToDateTableFieldsArray[i]; const column = upToDateTableFieldsArray[i];
const prevColumn = upToDateTableFieldsArray[i - 1]; const prevColumn = upToDateTableFieldsArray[i - 1];
const nextColumn = upToDateTableFieldsArray[i + 1]; const nextColumn = upToDateTableFieldsArray[i + 1];
const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, foreignKey, updatedField } = column; const { fieldName, dataType, nullValue, primaryKey, autoIncrement, defaultValue, defaultValueLiteral, foreignKey, updatedField } = column;
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Skip default fields * @description Skip default fields
*/ */
if (fieldName.match(/^id$|^date_/)) continue; if (fieldName.match(/^id$|^date_/)) continue;
/** /**
* @description Skip columns that have been updated recently * @description Skip columns that have been updated recently
*/ */
// if (updatedColumnsArray.includes(fieldName)) continue; // if (updatedColumnsArray.includes(fieldName)) continue;
//////////////////////////////////////// ////////////////////////////////////////
let updateText = ""; let updateText = "";
//////////////////////////////////////// ////////////////////////////////////////
let existingColumnIndex; let existingColumnIndex;
/** /**
* @description Existing MYSQL field object * @description Existing MYSQL field object
*/ */
let existingColumn = let existingColumn =
allExistingColumns && allExistingColumns[0] allExistingColumns && allExistingColumns[0]
? allExistingColumns.filter((_column, _index) => { ? allExistingColumns.filter((_column, _index) => {
if (_column.Field === fieldName) { if (_column.Field === fieldName) {
existingColumnIndex = _index; existingColumnIndex = _index;
return true; return true;
} }
}) })
: null; : null;
/** /**
* @description Construct SQL text snippet for this field * @description Construct SQL text snippet for this field
*/ */
let { fieldEntryText } = generateColumnDescription({ columnData: column }); let { fieldEntryText } = generateColumnDescription({ columnData: column });
/** /**
* @description Modify Column(Field) if it already exists * @description Modify Column(Field) if it already exists
* in MYSQL database * in MYSQL database
*/ */
if (existingColumn && existingColumn[0]?.Field) { if (existingColumn && existingColumn[0]?.Field) {
const { Field, Type, Null, Key, Default, Extra } = existingColumn[0]; const { Field, Type, Null, Key, Default, Extra } = existingColumn[0];
let isColumnReordered = existingColumnIndex ? i < existingColumnIndex : false; let isColumnReordered = existingColumnIndex ? i < existingColumnIndex : false;
if (Field === fieldName && !isColumnReordered && dataType.toUpperCase() === Type.toUpperCase()) { if (Field === fieldName && !isColumnReordered && dataType.toUpperCase() === Type.toUpperCase()) {
updateText += `MODIFY COLUMN ${fieldEntryText}`; updateText += `MODIFY COLUMN ${fieldEntryText}`;
// continue; // continue;
} else { } else {
updateText += `MODIFY COLUMN ${fieldEntryText}${isColumnReordered ? (prevColumn?.fieldName ? " AFTER `" + prevColumn.fieldName + "`" : " AFTER `id`") : ""}`; updateText += `MODIFY COLUMN ${fieldEntryText}${isColumnReordered ? (prevColumn?.fieldName ? " AFTER `" + prevColumn.fieldName + "`" : " AFTER `id`") : ""}`;
// if (userId) { // if (userId) {
// } else { // } else {
// updateText += `MODIFY COLUMN ${fieldEntryText}`; // updateText += `MODIFY COLUMN ${fieldEntryText}`;
// } // }
} }
} else if (prevColumn && prevColumn.fieldName) { } else if (prevColumn && prevColumn.fieldName) {
/** /**
* @description Add new Column AFTER previous column, if * @description Add new Column AFTER previous column, if
* previous column exists * previous column exists
*/ */
updateText += `ADD COLUMN ${fieldEntryText} AFTER \`${prevColumn.fieldName}\``; updateText += `ADD COLUMN ${fieldEntryText} AFTER \`${prevColumn.fieldName}\``;
} else if (!prevColumn && nextColumn && nextColumn.fieldName) { } else if (!prevColumn && nextColumn && nextColumn.fieldName) {
/** /**
* @description Add new Column before next column, if * @description Add new Column before next column, if
* next column exists * next column exists
*/ */
updateText += `ADD COLUMN ${fieldEntryText} AFTER \`id\``; updateText += `ADD COLUMN ${fieldEntryText} AFTER \`id\``;
} else { } else {
/** /**
* @description Append new column to the end of existing columns * @description Append new column to the end of existing columns
*/ */
updateText += `ADD COLUMN ${fieldEntryText}`; updateText += `ADD COLUMN ${fieldEntryText}`;
} }
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Pust SQL code snippet to updateTableQueryArray Array * @description Pust SQL code snippet to updateTableQueryArray Array
* Add a comma(,) to separate from the next snippet * Add a comma(,) to separate from the next snippet
*/ */
updateTableQueryArray.push(updateText + ","); updateTableQueryArray.push(updateText + ",");
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Handle foreing keys if available, and if there is no * @description Handle foreing keys if available, and if there is no
* "clone" boolean = true * "clone" boolean = true
*/ */
if (!clone && foreignKey) { if (!clone && foreignKey) {
const { destinationTableName, destinationTableColumnName, cascadeDelete, cascadeUpdate, foreignKeyName } = foreignKey; const { destinationTableName, destinationTableColumnName, cascadeDelete, cascadeUpdate, foreignKeyName } = foreignKey;
const foreinKeyText = `ADD CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (${fieldName}) REFERENCES ${destinationTableName}(${destinationTableColumnName})${cascadeDelete ? " ON DELETE CASCADE" : ""}${cascadeUpdate ? " ON UPDATE CASCADE" : ""}`; const foreinKeyText = `ADD CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (${fieldName}) REFERENCES ${destinationTableName}(${destinationTableColumnName})${cascadeDelete ? " ON DELETE CASCADE" : ""}${cascadeUpdate ? " ON UPDATE CASCADE" : ""}`;
// const foreinKeyText = `ADD CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (${fieldName}) REFERENCES ${destinationTableName}(${destinationTableColumnName})${cascadeDelete ? " ON DELETE CASCADE" : ""}${cascadeUpdate ? " ON UPDATE CASCADE" : ""}` + ","; // const foreinKeyText = `ADD CONSTRAINT \`${foreignKeyName}\` FOREIGN KEY (${fieldName}) REFERENCES ${destinationTableName}(${destinationTableColumnName})${cascadeDelete ? " ON DELETE CASCADE" : ""}${cascadeUpdate ? " ON UPDATE CASCADE" : ""}` + ",";
const finalQueryString = `ALTER TABLE \`${tableName}\` ${foreinKeyText}`; const finalQueryString = `ALTER TABLE \`${tableName}\` ${foreinKeyText}`;
const addForeignKey = await varDatabaseDbHandler({ const addForeignKey = await varDatabaseDbHandler({
database: dbFullName, database: dbFullName,
queryString: finalQueryString, queryString: finalQueryString,
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
} }
/** /**
* @description Construct final SQL query by combning all SQL snippets in * @description Construct final SQL query by combning all SQL snippets in
* updateTableQueryArray Arry, and trimming the final comma(,) * updateTableQueryArray Arry, and trimming the final comma(,)
*/ */
const updateTableQuery = updateTableQueryArray.join(" ").replace(/,$/, ""); const updateTableQuery = updateTableQueryArray.join(" ").replace(/,$/, "");
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @description Check if SQL snippets array has more than 1 entries * @description Check if SQL snippets array has more than 1 entries
* This is because 1 entry means "ALTER TABLE table_name" only, without any * This is because 1 entry means "ALTER TABLE table_name" only, without any
* Alter directives like "ADD COLUMN" or "MODIFY COLUMN" * Alter directives like "ADD COLUMN" or "MODIFY COLUMN"
*/ */
if (updateTableQueryArray.length > 1) { if (updateTableQueryArray.length > 1) {
const updateTable = await varDatabaseDbHandler({ const updateTable = await varDatabaseDbHandler({
queryString: updateTableQuery, queryString: updateTableQuery,
database: dbFullName, database: dbFullName,
}); });
return updateTable; return updateTable;
} else { } else {
/** /**
* @description If only 1 SQL snippet is left in updateTableQueryArray, this * @description If only 1 SQL snippet is left in updateTableQueryArray, this
* means that no updates have been made to the table * means that no updates have been made to the table
*/ */
return "No Changes Made to Table"; return "No Changes Made to Table";
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log('Error in "updateTable" function =>', error.message); console.log('Error in "updateTable" function =>', error.message);
return "Error in Updating Table"; return "Error in Updating Table";
} }
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -1,98 +1,98 @@
/** # MODULE TRACE /** # MODULE TRACE
====================================================================== ======================================================================
* Detected 9 files that call this module. The files are listed below: * Detected 9 files that call this module. The files are listed below:
====================================================================== ======================================================================
* `require` Statement Found in [createDbFromSchema.js](d:\GitHub\dsql\engine\engine\createDbFromSchema.js) * `require` Statement Found in [createDbFromSchema.js](d:\GitHub\dsql\engine\engine\createDbFromSchema.js)
* `require` Statement Found in [updateTable.js](d:\GitHub\dsql\engine\engine\utils\updateTable.js) * `require` Statement Found in [updateTable.js](d:\GitHub\dsql\engine\engine\utils\updateTable.js)
* `require` Statement Found in [runQuery.js](d:\GitHub\dsql\engine\query\utils\runQuery.js) * `require` Statement Found in [runQuery.js](d:\GitHub\dsql\engine\query\utils\runQuery.js)
* `require` Statement Found in [add-user.js](d:\GitHub\dsql\engine\user\add-user.js) * `require` Statement Found in [add-user.js](d:\GitHub\dsql\engine\user\add-user.js)
* `require` Statement Found in [get-user.js](d:\GitHub\dsql\engine\user\get-user.js) * `require` Statement Found in [get-user.js](d:\GitHub\dsql\engine\user\get-user.js)
* `require` Statement Found in [login-user.js](d:\GitHub\dsql\engine\user\login-user.js) * `require` Statement Found in [login-user.js](d:\GitHub\dsql\engine\user\login-user.js)
* `require` Statement Found in [reauth-user.js](d:\GitHub\dsql\engine\user\reauth-user.js) * `require` Statement Found in [reauth-user.js](d:\GitHub\dsql\engine\user\reauth-user.js)
* `require` Statement Found in [handleSocialDb.js](d:\GitHub\dsql\engine\user\social\utils\handleSocialDb.js) * `require` Statement Found in [handleSocialDb.js](d:\GitHub\dsql\engine\user\social\utils\handleSocialDb.js)
* `require` Statement Found in [update-user.js](d:\GitHub\dsql\engine\user\update-user.js) * `require` Statement Found in [update-user.js](d:\GitHub\dsql\engine\user\update-user.js)
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check // @ts-check
const fs = require("fs"); const fs = require("fs");
const parseDbResults = require("./parseDbResults"); const parseDbResults = require("./parseDbResults");
const dbHandler = require("./dbHandler"); const dbHandler = require("./dbHandler");
/** /**
* DB handler for specific database * DB handler for specific database
* ============================================================================== * ==============================================================================
* @async * @async
* @param {object} params - Single object params * @param {object} params - Single object params
* @param {string} params.queryString - SQL string * @param {string} params.queryString - SQL string
* @param {string[]} [params.queryValuesArray] - Values Array * @param {string[]} [params.queryValuesArray] - Values Array
* @param {string} params.database - Database name * @param {string} params.database - Database name
* @param {import("../../../types/database-schema.td").DSQL_TableSchemaType} [params.tableSchema] - Table schema * @param {import("../../../types/database-schema.td").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
module.exports = async function varDatabaseDbHandler({ queryString, queryValuesArray, database, tableSchema }) { module.exports = async function varDatabaseDbHandler({ queryString, queryValuesArray, database, tableSchema }) {
/** /**
* Create Connection * Create Connection
* *
* @description Create Connection * @description Create Connection
*/ */
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
* @type {*} * @type {*}
*/ */
let results; let results;
/** /**
* Fetch from db * Fetch from db
* *
* @description Fetch data from db if no cache * @description Fetch data from db if no cache
*/ */
try { try {
if (queryString && Array.isArray(queryValuesArray) && queryValuesArray[0]) { if (queryString && Array.isArray(queryValuesArray) && queryValuesArray[0]) {
results = await dbHandler({ query: queryString, values: queryValuesArray, database: database }); results = await dbHandler({ query: queryString, values: queryValuesArray, database: database });
} else if (queryString && !Array.isArray(queryValuesArray)) { } else if (queryString && !Array.isArray(queryValuesArray)) {
results = await dbHandler({ query: queryString, database: database }); results = await dbHandler({ query: queryString, database: database });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (error) { } catch (error) {
console.log("\x1b[31mvarDatabaseDbHandler ERROR\x1b[0m =>", database, error); console.log("\x1b[31mvarDatabaseDbHandler ERROR\x1b[0m =>", database, error);
} }
/** /**
* Return results * Return results
* *
* @description Return results add to cache if "req" param is passed * @description Return results add to cache if "req" param is passed
*/ */
if (results && tableSchema) { if (results && tableSchema) {
try { try {
const unparsedResults = results; const unparsedResults = results;
// deepcode ignore reDOS: <please specify a reason of ignoring this> // deepcode ignore reDOS: <please specify a reason of ignoring this>
const parsedResults = await parseDbResults({ unparsedResults: unparsedResults, tableSchema: tableSchema }); const parsedResults = await parseDbResults({ unparsedResults: unparsedResults, tableSchema: tableSchema });
return parsedResults; return parsedResults;
} catch (error) { } catch (error) {
console.log("\x1b[31mvarDatabaseDbHandler ERROR\x1b[0m =>", database, error); console.log("\x1b[31mvarDatabaseDbHandler ERROR\x1b[0m =>", database, error);
return null; return null;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} else if (results) { } else if (results) {
return results; return results;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} else { } else {
return null; return null;
} }
}; };

View File

@ -1,101 +1,101 @@
/** # MODULE TRACE /** # MODULE TRACE
====================================================================== ======================================================================
* No imports found for this Module * No imports found for this Module
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check // @ts-check
const runQuery = require("./utils/runQuery"); const runQuery = require("./utils/runQuery");
/** /**
* @typedef {Object} LocalGetReturn * @typedef {Object} LocalGetReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {*} [payload] - GET request results * @property {*} [payload] - GET request results
* @property {string} [msg] - Message * @property {string} [msg] - Message
* @property {string} [error] - Error Message * @property {string} [error] - Error Message
*/ */
/** /**
* @typedef {Object} LocalQueryObject * @typedef {Object} LocalQueryObject
* @property {string} query - Table Name * @property {string} query - Table Name
* @property {string} [tableName] - Table Name * @property {string} [tableName] - Table Name
* @property {string[]} [queryValues] - GET request results * @property {string[]} [queryValues] - GET request results
*/ */
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {LocalQueryObject} params.options - SQL Query * @param {LocalQueryObject} params.options - SQL Query
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Name of the table to query * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Name of the table to query
* *
* @returns { Promise<LocalGetReturn> } - Return Object * @returns { Promise<LocalGetReturn> } - Return Object
*/ */
async function localGet({ options, dbSchema }) { async function localGet({ options, dbSchema }) {
try { try {
const { query, queryValues } = options; const { query, queryValues } = options;
/** @type {string | undefined | any } */ /** @type {string | undefined | any } */
const tableName = options?.tableName ? options.tableName : undefined; const tableName = options?.tableName ? options.tableName : undefined;
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
/** /**
* Input Validation * Input Validation
* *
* @description Input Validation * @description Input Validation
*/ */
if (typeof query == "string" && (query.match(/^alter|^delete|information_schema|databases|^create/i) || !query.match(/^select/i))) { if (typeof query == "string" && (query.match(/^alter|^delete|information_schema|databases|^create/i) || !query.match(/^select/i))) {
return { success: false, msg: "Wrong Input" }; return { success: false, msg: "Wrong Input" };
} }
/** /**
* Create new user folder and file * Create new user folder and file
* *
* @description Create new user folder and file * @description Create new user folder and file
*/ */
let results; let results;
try { try {
let { result, error } = await runQuery({ let { result, error } = await runQuery({
dbFullName: dbFullName, dbFullName: dbFullName,
query: query, query: query,
queryValuesArray: queryValues, queryValuesArray: queryValues,
dbSchema, dbSchema,
tableName, tableName,
}); });
if (error) throw error; if (error) throw error;
if (!result) throw new Error("No Result received for query => " + query); if (!result) throw new Error("No Result received for query => " + query);
if (result?.error) throw new Error(result.error); if (result?.error) throw new Error(result.error);
results = result; results = result;
return { success: true, payload: results }; return { success: true, payload: results };
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
console.log("Error in local get Request =>", error.message); console.log("Error in local get Request =>", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
error: error.message, error: error.message,
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
console.log("Error in local get Request =>", error.message); console.log("Error in local get Request =>", error.message);
return { success: false, msg: "Something went wrong!" }; return { success: false, msg: "Something went wrong!" };
//////////////////////////////////////// ////////////////////////////////////////
} }
} }
module.exports = localGet; module.exports = localGet;

View File

@ -1,100 +1,100 @@
// @ts-check // @ts-check
const runQuery = require("./utils/runQuery"); const runQuery = require("./utils/runQuery");
/** /**
* @typedef {Object} LocalPostReturn * @typedef {Object} LocalPostReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {*} [payload] - GET request results * @property {*} [payload] - GET request results
* @property {string} [msg] - Message * @property {string} [msg] - Message
* @property {string} [error] - Error Message * @property {string} [error] - Error Message
*/ */
/** /**
* @typedef {Object} LocalPostQueryObject * @typedef {Object} LocalPostQueryObject
* @property {string | import("../../utils/post").PostDataPayload} query - Table Name * @property {string | import("../../utils/post").PostDataPayload} query - Table Name
* @property {string} [tableName] - Table Name * @property {string} [tableName] - Table Name
* @property {string[]} [queryValues] - GET request results * @property {string[]} [queryValues] - GET request results
*/ */
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {LocalPostQueryObject} params.options - SQL Query * @param {LocalPostQueryObject} params.options - SQL Query
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Name of the table to query * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Name of the table to query
* *
* @returns { Promise<LocalPostReturn> } - Return Object * @returns { Promise<LocalPostReturn> } - Return Object
*/ */
async function localPost({ options, dbSchema }) { async function localPost({ options, dbSchema }) {
try { try {
/** /**
* Grab Body * Grab Body
*/ */
const { query, tableName, queryValues } = options; const { query, tableName, queryValues } = options;
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
/** /**
* Input Validation * Input Validation
* *
* @description Input Validation * @description Input Validation
*/ */
if (typeof query === "string" && query?.match(/^create |^alter |^drop /i)) { if (typeof query === "string" && query?.match(/^create |^alter |^drop /i)) {
return { success: false, msg: "Wrong Input" }; return { success: false, msg: "Wrong Input" };
} }
if (typeof query === "object" && query?.action?.match(/^create |^alter |^drop /i)) { if (typeof query === "object" && query?.action?.match(/^create |^alter |^drop /i)) {
return { success: false, msg: "Wrong Input" }; return { success: false, msg: "Wrong Input" };
} }
/** /**
* Create new user folder and file * Create new user folder and file
* *
* @description Create new user folder and file * @description Create new user folder and file
*/ */
try { try {
let { result, error } = await runQuery({ let { result, error } = await runQuery({
dbFullName: dbFullName, dbFullName: dbFullName,
query: query, query: query,
dbSchema: dbSchema, dbSchema: dbSchema,
queryValuesArray: queryValues, queryValuesArray: queryValues,
tableName, tableName,
}); });
if (error) throw error; if (error) throw error;
return { return {
success: true, success: true,
payload: result, payload: result,
error: error, error: error,
}; };
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
return { return {
success: false, success: false,
payload: null, payload: null,
error: error.message, error: error.message,
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
console.log("Error in local post Request =>", error.message); console.log("Error in local post Request =>", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Something went wrong!", msg: "Something went wrong!",
}; };
//////////////////////////////////////// ////////////////////////////////////////
} }
} }
module.exports = localPost; module.exports = localPost;

View File

@ -1,143 +1,143 @@
// @ts-check // @ts-check
/** /**
* Imports * Imports
*/ */
const https = require("https"); const https = require("https");
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} PostReturn * @typedef {Object} PostReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {*} [payload] - The Y Coordinate * @property {*} [payload] - The Y Coordinate
* @property {string} [error] - The Y Coordinate * @property {string} [error] - The Y Coordinate
*/ */
/** /**
* # Update API Schema From Local DB * # Update API Schema From Local DB
* *
* @async * @async
* *
* @returns { Promise<PostReturn> } - Return Object * @returns { Promise<PostReturn> } - Return Object
*/ */
async function updateApiSchemaFromLocalDb() { async function updateApiSchemaFromLocalDb() {
try { try {
/** /**
* Initialize * Initialize
*/ */
const dbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const dbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
const key = process.env.DSQL_KEY || ""; const key = process.env.DSQL_KEY || "";
const dbSchema = JSON.parse(fs.readFileSync(dbSchemaPath, "utf8")); const dbSchema = JSON.parse(fs.readFileSync(dbSchemaPath, "utf8"));
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayloadString = JSON.stringify({ const reqPayloadString = JSON.stringify({
schema: dbSchema, schema: dbSchema,
}).replace(/\n|\r|\n\r/gm, ""); }).replace(/\n|\r|\n\r/gm, "");
try { try {
JSON.parse(reqPayloadString); JSON.parse(reqPayloadString);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
console.log(reqPayloadString); console.log(reqPayloadString);
return { return {
success: false, success: false,
payload: null, payload: null,
error: "Query object is invalid. Please Check query data values", error: "Query object is invalid. Please Check query data values",
}; };
} }
const reqPayload = reqPayloadString; const reqPayload = reqPayloadString;
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/query/update-schema-from-single-database`, path: `/api/query/update-schema-from-single-database`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
try { try {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
console.log("Fetched Payload =>", str); console.log("Fetched Payload =>", str);
resolve({ resolve({
success: false, success: false,
payload: null, payload: null,
error: error, error: error,
}); });
} }
}); });
response.on("error", (err) => { response.on("error", (err) => {
resolve({ resolve({
success: false, success: false,
payload: null, payload: null,
error: err.message, error: err.message,
}); });
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.on("error", (error) => { httpsRequest.on("error", (error) => {
console.log("HTTPS request ERROR =>", error); console.log("HTTPS request ERROR =>", error);
}); });
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
return { return {
success: false, success: false,
payload: null, payload: null,
error: error.message, error: error.message,
}; };
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = updateApiSchemaFromLocalDb; module.exports = updateApiSchemaFromLocalDb;

View File

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

View File

@ -1,76 +1,76 @@
// @ts-check // @ts-check
const dbHandler = require("../../engine/utils/dbHandler"); const dbHandler = require("../../engine/utils/dbHandler");
/** /**
* Imports: Handle imports * Imports: Handle imports
*/ */
/** /**
* Delete DB Entry Function * Delete DB Entry Function
* ============================================================================== * ==============================================================================
* @description Description * @description Description
* @async * @async
* *
* @param {object} params - An object containing the function parameters. * @param {object} params - An object containing the function parameters.
* @param {string} [params.dbContext] - What is the database context? "Master" * @param {string} [params.dbContext] - What is the database context? "Master"
* or "Dsql User". Defaults to "Master" * or "Dsql User". Defaults to "Master"
* @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"? * @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"?
* "Read only" or "Full Access"? Defaults to "Read Only" * "Read only" or "Full Access"? Defaults to "Read Only"
* @param {string} params.dbFullName - Database full name * @param {string} params.dbFullName - Database full name
* @param {string} params.tableName - Table name * @param {string} params.tableName - Table name
* @param {import("../../../types/database-schema.td").DSQL_TableSchemaType} [params.tableSchema] - Table schema * @param {import("../../../types/database-schema.td").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @param {string} params.identifierColumnName - Update row identifier column name * @param {string} params.identifierColumnName - Update row identifier column name
* @param {string|number} params.identifierValue - Update row identifier column value * @param {string|number} params.identifierValue - Update row identifier column value
* *
* @returns {Promise<object|null>} * @returns {Promise<object|null>}
*/ */
async function deleteDbEntry({ dbContext, paradigm, dbFullName, tableName, identifierColumnName, identifierValue }) { async function deleteDbEntry({ dbContext, paradigm, dbFullName, tableName, identifierColumnName, identifierValue }) {
try { try {
/** /**
* Check if data is valid * Check if data is valid
*/ */
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Execution * Execution
* *
* @description * @description
*/ */
const query = `DELETE FROM ${tableName} WHERE \`${identifierColumnName}\`=?`; const query = `DELETE FROM ${tableName} WHERE \`${identifierColumnName}\`=?`;
const deletedEntry = await dbHandler({ const deletedEntry = await dbHandler({
query: query, query: query,
database: dbFullName, database: dbFullName,
values: [identifierValue], values: [identifierValue],
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Return statement * Return statement
*/ */
return deletedEntry; return deletedEntry;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (error) { } catch (error) {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return null; return null;
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = deleteDbEntry; module.exports = deleteDbEntry;

View File

@ -1,165 +1,165 @@
/** # MODULE TRACE /** # MODULE TRACE
====================================================================== ======================================================================
* Detected 4 files that call this module. The files are listed below: * Detected 4 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 [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 [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 [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) * `require` Statement Found in [update-user.js](d:\GitHub\dsql\engine\user\update-user.js)
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check // @ts-check
const fs = require("fs"); const fs = require("fs");
const addDbEntry = require("./addDbEntry"); const addDbEntry = require("./addDbEntry");
const updateDbEntry = require("./updateDbEntry"); const updateDbEntry = require("./updateDbEntry");
const deleteDbEntry = require("./deleteDbEntry"); const deleteDbEntry = require("./deleteDbEntry");
const varDatabaseDbHandler = require("../../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../../engine/utils/varDatabaseDbHandler");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* Run DSQL users queries * Run DSQL users queries
* ============================================================================== * ==============================================================================
* @param {object} params - An object containing the function parameters. * @param {object} params - An object containing the function parameters.
* @param {string} params.dbFullName - Database full name. Eg. "datasquire_user_2_test" * @param {string} params.dbFullName - Database full name. Eg. "datasquire_user_2_test"
* @param {*} params.query - Query string or object * @param {*} params.query - Query string or object
* @param {boolean} [params.readOnly] - Is this operation read only? * @param {boolean} [params.readOnly] - Is this operation read only?
* @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Database schema * @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Database schema
* @param {string[]} [params.queryValuesArray] - An optional array of query values if "?" is used in the query string * @param {string[]} [params.queryValuesArray] - An optional array of query values if "?" is used in the query string
* @param {string} [params.tableName] - Table Name * @param {string} [params.tableName] - Table Name
* *
* @return {Promise<{result: *, error?: *}>} * @return {Promise<{result: *, error?: *}>}
*/ */
async function runQuery({ dbFullName, query, readOnly, dbSchema, queryValuesArray, tableName }) { async function runQuery({ dbFullName, query, readOnly, dbSchema, queryValuesArray, tableName }) {
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
let result, error, tableSchema; let result, error, tableSchema;
if (dbSchema) { if (dbSchema) {
try { try {
const table = tableName ? tableName : typeof query == "string" ? null : query ? query?.table : null; const table = tableName ? tableName : typeof query == "string" ? null : query ? query?.table : null;
if (!table) throw new Error("No table name provided"); if (!table) throw new Error("No table name provided");
tableSchema = dbSchema.tables.filter((tb) => tb?.tableName === table)[0]; tableSchema = dbSchema.tables.filter((tb) => tb?.tableName === table)[0];
} catch (_err) {} } catch (_err) {}
} }
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
try { try {
if (typeof query === "string") { if (typeof query === "string") {
result = await varDatabaseDbHandler({ result = await varDatabaseDbHandler({
queryString: query, queryString: query,
queryValuesArray, queryValuesArray,
database: dbFullName, database: dbFullName,
tableSchema, tableSchema,
}); });
} else if (typeof query === "object") { } else if (typeof query === "object") {
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
const { data, action, table, identifierColumnName, identifierValue, update, duplicateColumnName, duplicateColumnValue } = query; const { data, action, table, identifierColumnName, identifierValue, update, duplicateColumnName, duplicateColumnValue } = query;
switch (action.toLowerCase()) { switch (action.toLowerCase()) {
case "insert": case "insert":
result = await addDbEntry({ result = await addDbEntry({
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: table, tableName: table,
data: data, data: data,
update, update,
duplicateColumnName, duplicateColumnName,
duplicateColumnValue, duplicateColumnValue,
tableSchema, tableSchema,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
if (!result?.insertId) { if (!result?.insertId) {
error = new Error("Couldn't insert data"); error = new Error("Couldn't insert data");
} }
break; break;
case "update": case "update":
result = await updateDbEntry({ result = await updateDbEntry({
dbContext: "Dsql User", dbContext: "Dsql User",
paradigm: "Full Access", paradigm: "Full Access",
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: table, tableName: table,
data: data, data: data,
identifierColumnName, identifierColumnName,
identifierValue, identifierValue,
tableSchema, tableSchema,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
break; break;
case "delete": case "delete":
result = await deleteDbEntry({ result = await deleteDbEntry({
dbContext: "Dsql User", dbContext: "Dsql User",
paradigm: "Full Access", paradigm: "Full Access",
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: table, tableName: table,
identifierColumnName, identifierColumnName,
identifierValue, identifierValue,
tableSchema, tableSchema,
}); });
break; break;
default: default:
console.log("Unhandled Query"); console.log("Unhandled Query");
console.log("Query Recieved =>", query); console.log("Query Recieved =>", query);
result = { result = {
result: null, result: null,
error: "Unhandled Query", error: "Unhandled Query",
}; };
break; break;
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in Running Query =>", error.message); console.log("Error in Running Query =>", error.message);
console.log("Query Recieved =>", query); console.log("Query Recieved =>", query);
result = { result = {
result: null, result: null,
error: "Error in running Query => " + error.message, error: "Error in running Query => " + error.message,
}; };
error = error.message; error = error.message;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return { result, error }; return { result, error };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} }
module.exports = runQuery; module.exports = runQuery;

View File

@ -1,149 +1,149 @@
// @ts-check // @ts-check
const encrypt = require("../../../functions/encrypt"); const encrypt = require("../../../functions/encrypt");
const dbHandler = require("../../engine/utils/dbHandler"); const dbHandler = require("../../engine/utils/dbHandler");
/** /**
* Imports: Handle imports * Imports: Handle imports
*/ */
/** /**
* Update DB Function * Update DB Function
* ============================================================================== * ==============================================================================
* @description Description * @description Description
* @async * @async
* *
* @param {object} params - An object containing the function parameters. * @param {object} params - An object containing the function parameters.
* @param {("Master" | "Dsql User")} [params.dbContext] - What is the database context? "Master" * @param {("Master" | "Dsql User")} [params.dbContext] - What is the database context? "Master"
* or "Dsql User". Defaults to "Master" * or "Dsql User". Defaults to "Master"
* @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"? * @param {("Read Only" | "Full Access")} [params.paradigm] - What is the paradigm for "Dsql User"?
* "Read only" or "Full Access"? Defaults to "Read Only" * "Read only" or "Full Access"? Defaults to "Read Only"
* @param {string} params.dbFullName - Database full name * @param {string} params.dbFullName - Database full name
* @param {string} params.tableName - Table name * @param {string} params.tableName - Table name
* @param {*} params.data - Data to add * @param {*} params.data - Data to add
* @param {import("../../../types/database-schema.td").DSQL_TableSchemaType} [params.tableSchema] - Table schema * @param {import("../../../types/database-schema.td").DSQL_TableSchemaType} [params.tableSchema] - Table schema
* @param {string} params.identifierColumnName - Update row identifier column name * @param {string} params.identifierColumnName - Update row identifier column name
* @param {string | number} params.identifierValue - Update row identifier column value * @param {string | number} params.identifierValue - Update row identifier column value
* @param {string} params.encryptionKey - Encryption key * @param {string} params.encryptionKey - Encryption key
* @param {string} params.encryptionSalt - Encryption salt * @param {string} params.encryptionSalt - Encryption salt
* *
* @returns {Promise<object|null>} * @returns {Promise<object|null>}
*/ */
async function updateDbEntry({ dbContext, paradigm, dbFullName, tableName, data, tableSchema, identifierColumnName, identifierValue, encryptionKey, encryptionSalt }) { async function updateDbEntry({ dbContext, paradigm, dbFullName, tableName, data, tableSchema, identifierColumnName, identifierValue, encryptionKey, encryptionSalt }) {
/** /**
* Check if data is valid * Check if data is valid
*/ */
if (!data || !Object.keys(data).length) return null; if (!data || !Object.keys(data).length) return null;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
const dataKeys = Object.keys(data); const dataKeys = Object.keys(data);
let updateKeyValueArray = []; let updateKeyValueArray = [];
let updateValues = []; let updateValues = [];
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
for (let i = 0; i < dataKeys.length; i++) { for (let i = 0; i < dataKeys.length; i++) {
try { try {
const dataKey = dataKeys[i]; const dataKey = dataKeys[i];
let value = data[dataKey]; let value = data[dataKey];
const targetFieldSchemaArray = tableSchema ? tableSchema?.fields?.filter((field) => field.fieldName === dataKey) : null; const targetFieldSchemaArray = tableSchema ? tableSchema?.fields?.filter((field) => field.fieldName === dataKey) : null;
const targetFieldSchema = targetFieldSchemaArray && targetFieldSchemaArray[0] ? targetFieldSchemaArray[0] : null; const targetFieldSchema = targetFieldSchemaArray && targetFieldSchemaArray[0] ? targetFieldSchemaArray[0] : null;
if (typeof value == "undefined") continue; if (typeof value == "undefined") continue;
if (typeof value !== "string" && typeof value !== "number" && !value) continue; if (typeof value !== "string" && typeof value !== "number" && !value) continue;
if (targetFieldSchema?.encrypted) { if (targetFieldSchema?.encrypted) {
value = encrypt({ data: value, encryptionKey, encryptionSalt }); value = encrypt({ data: value, encryptionKey, encryptionSalt });
} }
if (typeof value === "object") { if (typeof value === "object") {
value = JSON.stringify(value); value = JSON.stringify(value);
} }
if (typeof value === "string" && value.match(/^null$/i)) { if (typeof value === "string" && value.match(/^null$/i)) {
value = { value = {
toSqlString: function () { toSqlString: function () {
return "NULL"; return "NULL";
}, },
}; };
} }
if (targetFieldSchema?.pattern) { if (targetFieldSchema?.pattern) {
const pattern = new RegExp(targetFieldSchema.pattern, targetFieldSchema.patternFlags || ""); const pattern = new RegExp(targetFieldSchema.pattern, targetFieldSchema.patternFlags || "");
if (!value?.toString()?.match(pattern)) { if (!value?.toString()?.match(pattern)) {
console.log("DSQL: Pattern not matched =>", value); console.log("DSQL: Pattern not matched =>", value);
value = ""; value = "";
} }
} }
if (typeof value === "string" && !value.match(/./i)) { if (typeof value === "string" && !value.match(/./i)) {
value = { value = {
toSqlString: function () { toSqlString: function () {
return "NULL"; return "NULL";
}, },
}; };
} }
if (!value && typeof value == "number" && value != 0) continue; if (!value && typeof value == "number" && value != 0) continue;
updateKeyValueArray.push(`\`${dataKey}\`=?`); updateKeyValueArray.push(`\`${dataKey}\`=?`);
updateValues.push(value); updateValues.push(value);
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
console.log("DSQL: Error in parsing data keys in update function =>", error.message); console.log("DSQL: Error in parsing data keys in update function =>", error.message);
continue; continue;
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
updateKeyValueArray.push(`date_updated='${Date()}'`); updateKeyValueArray.push(`date_updated='${Date()}'`);
updateKeyValueArray.push(`date_updated_code='${Date.now()}'`); updateKeyValueArray.push(`date_updated_code='${Date.now()}'`);
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const query = `UPDATE ${tableName} SET ${updateKeyValueArray.join(",")} WHERE \`${identifierColumnName}\`=?`; const query = `UPDATE ${tableName} SET ${updateKeyValueArray.join(",")} WHERE \`${identifierColumnName}\`=?`;
updateValues.push(identifierValue); updateValues.push(identifierValue);
const updatedEntry = await dbHandler({ const updatedEntry = await dbHandler({
database: dbFullName, database: dbFullName,
query: query, query: query,
values: updateValues, values: updateValues,
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Return statement * Return statement
*/ */
return updatedEntry; return updatedEntry;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = updateDbEntry; module.exports = updateDbEntry;

View File

@ -1,153 +1,153 @@
// @ts-check // @ts-check
const hashPassword = require("../../functions/hashPassword"); const hashPassword = require("../../functions/hashPassword");
const addUsersTableToDb = require("../engine/addUsersTableToDb"); const addUsersTableToDb = require("../engine/addUsersTableToDb");
const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler");
const addDbEntry = require("../query/utils/addDbEntry"); const addDbEntry = require("../query/utils/addDbEntry");
const runQuery = require("../query/utils/runQuery"); const runQuery = require("../query/utils/runQuery");
/** /**
* @typedef {Object} LocalPostReturn * @typedef {Object} LocalPostReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {*} [payload] - GET request results * @property {*} [payload] - GET request results
* @property {string} [msg] - Message * @property {string} [msg] - Message
* @property {string} [error] - Error Message * @property {string} [error] - Error Message
*/ */
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {import("../../users/add-user").UserDataPayload} params.payload - SQL Query * @param {import("../../users/add-user").UserDataPayload} params.payload - SQL Query
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema - Name of the table to query * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema - Name of the table to query
* *
* @returns { Promise<LocalPostReturn> } - Return Object * @returns { Promise<LocalPostReturn> } - Return Object
*/ */
async function localAddUser({ payload, dbSchema }) { async function localAddUser({ payload, dbSchema }) {
try { try {
/** /**
* Initialize Variables * Initialize Variables
*/ */
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
/** /**
* Hash Password * Hash Password
* *
* @description Hash Password * @description Hash Password
*/ */
if (!payload?.password) { if (!payload?.password) {
return { success: false, payload: `Password is required to create an account` }; return { success: false, payload: `Password is required to create an account` };
} }
const hashedPassword = hashPassword({ const hashedPassword = hashPassword({
password: payload.password, password: payload.password,
encryptionKey, encryptionKey,
}); });
payload.password = hashedPassword; payload.password = hashedPassword;
let fields = await varDatabaseDbHandler({ let fields = await varDatabaseDbHandler({
queryString: `SHOW COLUMNS FROM users`, queryString: `SHOW COLUMNS FROM users`,
database: dbFullName, database: dbFullName,
}); });
if (!fields) { if (!fields) {
const newTable = await addUsersTableToDb({ dbSchema }); const newTable = await addUsersTableToDb({ dbSchema });
console.log(newTable); console.log(newTable);
fields = await varDatabaseDbHandler({ fields = await varDatabaseDbHandler({
queryString: `SHOW COLUMNS FROM users`, queryString: `SHOW COLUMNS FROM users`,
database: dbFullName, database: dbFullName,
}); });
} }
if (!fields) { if (!fields) {
return { return {
success: false, success: false,
payload: "Could not create users table", payload: "Could not create users table",
}; };
} }
const fieldsTitles = fields.map((/** @type {*} */ fieldObject) => fieldObject.Field); const fieldsTitles = fields.map((/** @type {*} */ fieldObject) => fieldObject.Field);
let invalidField = null; let invalidField = null;
for (let i = 0; i < Object.keys(payload).length; i++) { for (let i = 0; i < Object.keys(payload).length; i++) {
const key = Object.keys(payload)[i]; const key = Object.keys(payload)[i];
if (!fieldsTitles.includes(key)) { if (!fieldsTitles.includes(key)) {
invalidField = key; invalidField = key;
break; break;
} }
} }
if (invalidField) { if (invalidField) {
return { success: false, payload: `${invalidField} is not a valid field!` }; return { success: false, payload: `${invalidField} is not a valid field!` };
} }
const tableSchema = dbSchema.tables.find((tb) => tb?.tableName === "users"); const tableSchema = dbSchema.tables.find((tb) => tb?.tableName === "users");
const existingUser = await varDatabaseDbHandler({ const existingUser = await varDatabaseDbHandler({
queryString: `SELECT * FROM users WHERE email = ?${payload.username ? "OR username = ?" : ""}}`, queryString: `SELECT * FROM users WHERE email = ?${payload.username ? "OR username = ?" : ""}}`,
queryValuesArray: payload.username ? [payload.email, payload.username] : [payload.email], queryValuesArray: payload.username ? [payload.email, payload.username] : [payload.email],
database: dbFullName, database: dbFullName,
tableSchema: tableSchema, tableSchema: tableSchema,
}); });
if (existingUser && existingUser[0]) { if (existingUser && existingUser[0]) {
return { return {
success: false, success: false,
payload: "User Already Exists", payload: "User Already Exists",
}; };
} }
const addUser = await addDbEntry({ const addUser = await addDbEntry({
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: "users", tableName: "users",
data: { data: {
...payload, ...payload,
image: "/images/user_images/user-preset.png", image: "/images/user_images/user-preset.png",
image_thumbnail: "/images/user_images/user-preset-thumbnail.png", image_thumbnail: "/images/user_images/user-preset-thumbnail.png",
}, },
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
tableSchema, tableSchema,
}); });
if (addUser?.insertId) { if (addUser?.insertId) {
const newlyAddedUser = await varDatabaseDbHandler({ const newlyAddedUser = await varDatabaseDbHandler({
queryString: `SELECT id,first_name,last_name,email,username,phone,image,image_thumbnail,city,state,country,zip_code,address,verification_status,more_user_data FROM users WHERE id='${addUser.insertId}'`, queryString: `SELECT id,first_name,last_name,email,username,phone,image,image_thumbnail,city,state,country,zip_code,address,verification_status,more_user_data FROM users WHERE id='${addUser.insertId}'`,
database: dbFullName, database: dbFullName,
}); });
return { return {
success: true, success: true,
payload: newlyAddedUser?.[0], payload: newlyAddedUser?.[0],
}; };
} else { } else {
return { return {
success: false, success: false,
payload: "Could not create user", payload: "Could not create user",
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
console.log("Error in local add-user Request =>", error.message); console.log("Error in local add-user Request =>", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Something went wrong!", msg: "Something went wrong!",
}; };
//////////////////////////////////////// ////////////////////////////////////////
} }
} }
module.exports = localAddUser; module.exports = localAddUser;

View File

@ -1,53 +1,53 @@
// @ts-check // @ts-check
const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler");
/** /**
* *
* @param {object} param0 * @param {object} param0
* @param {number} param0.userId * @param {number} param0.userId
* @param {string[]} param0.fields * @param {string[]} param0.fields
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [param0.dbSchema] * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [param0.dbSchema]
* @returns * @returns
*/ */
async function getLocalUser({ userId, fields, dbSchema }) { async function getLocalUser({ userId, fields, dbSchema }) {
/** /**
* GRAB user * GRAB user
* *
* @description GRAB user * @description GRAB user
*/ */
const sanitizedFields = fields.map((fld) => fld.replace(/[^a-z\_]/g, "")); const sanitizedFields = fields.map((fld) => fld.replace(/[^a-z\_]/g, ""));
const query = `SELECT ${sanitizedFields.join(",")} FROM users WHERE id = ?`; const query = `SELECT ${sanitizedFields.join(",")} FROM users WHERE id = ?`;
const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users"); const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users");
let foundUser = await varDatabaseDbHandler({ let foundUser = await varDatabaseDbHandler({
queryString: query, queryString: query,
queryValuesArray: [userId.toString()], queryValuesArray: [userId.toString()],
database: process.env.DSQL_DB_NAME || "", database: process.env.DSQL_DB_NAME || "",
tableSchema, tableSchema,
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (!foundUser || !foundUser[0]) if (!foundUser || !foundUser[0])
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "User not found!", msg: "User not found!",
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** ********************* Send Response */ /** ********************* Send Response */
return { return {
success: true, success: true,
payload: foundUser[0], payload: foundUser[0],
}; };
} }
module.exports = getLocalUser; module.exports = getLocalUser;

View File

@ -1,152 +1,152 @@
// @ts-check // @ts-check
const hashPassword = require("../../functions/hashPassword"); const hashPassword = require("../../functions/hashPassword");
const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler");
/** /**
* *
* @param {object} param0 * @param {object} param0
* @param {{ * @param {{
* email?: string, * email?: string,
* username?: string, * username?: string,
* password: string, * password: string,
* }} param0.payload * }} param0.payload
* @param {string[]} [param0.additionalFields] * @param {string[]} [param0.additionalFields]
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [param0.dbSchema] * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [param0.dbSchema]
* @returns * @returns
*/ */
async function loginLocalUser({ payload, additionalFields, dbSchema }) { async function loginLocalUser({ payload, additionalFields, dbSchema }) {
try { try {
/** /**
* User auth * User auth
* *
* @description Authenticate user * @description Authenticate user
*/ */
const { email, username, password } = payload; const { email, username, password } = payload;
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
/** /**
* Check input validity * Check input validity
* *
* @description Check input validity * @description Check input validity
*/ */
if (email?.match(/ /) || username?.match(/ /) || password?.match(/ /)) { if (email?.match(/ /) || username?.match(/ /) || password?.match(/ /)) {
return { return {
success: false, success: false,
msg: "Invalid Email/Password format", msg: "Invalid Email/Password format",
}; };
} }
/** /**
* Password hash * Password hash
* *
* @description Password hash * @description Password hash
*/ */
let hashedPassword = hashPassword({ let hashedPassword = hashPassword({
password: password, password: password,
encryptionKey: encryptionKey, encryptionKey: encryptionKey,
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users"); const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users");
let foundUser = await varDatabaseDbHandler({ let foundUser = await varDatabaseDbHandler({
queryString: `SELECT * FROM users WHERE email = ? OR username = ?`, queryString: `SELECT * FROM users WHERE email = ? OR username = ?`,
queryValuesArray: [email || "", username || ""], queryValuesArray: [email || "", username || ""],
database: dbFullName.replace(/[^a-z0-9_]/g, ""), database: dbFullName.replace(/[^a-z0-9_]/g, ""),
tableSchema, tableSchema,
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (!foundUser || !foundUser[0]) if (!foundUser || !foundUser[0])
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "No user found", msg: "No user found",
}; };
let isPasswordCorrect = false; let isPasswordCorrect = false;
if (foundUser && foundUser[0]) { if (foundUser && foundUser[0]) {
isPasswordCorrect = hashedPassword === foundUser[0].password; isPasswordCorrect = hashedPassword === foundUser[0].password;
} }
let socialUserValid = false; let socialUserValid = false;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (!isPasswordCorrect && !socialUserValid) { if (!isPasswordCorrect && !socialUserValid) {
return { return {
success: false, success: false,
msg: "Wrong password, no social login validity", msg: "Wrong password, no social login validity",
payload: null, payload: null,
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
let csrfKey = Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2); let csrfKey = Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2);
let userPayload = { let userPayload = {
id: foundUser[0].id, id: foundUser[0].id,
first_name: foundUser[0].first_name, first_name: foundUser[0].first_name,
last_name: foundUser[0].last_name, last_name: foundUser[0].last_name,
username: foundUser[0].username, username: foundUser[0].username,
email: foundUser[0].email, email: foundUser[0].email,
phone: foundUser[0].phone, phone: foundUser[0].phone,
social_id: foundUser[0].social_id, social_id: foundUser[0].social_id,
image: foundUser[0].image, image: foundUser[0].image,
image_thumbnail: foundUser[0].image_thumbnail, image_thumbnail: foundUser[0].image_thumbnail,
verification_status: foundUser[0].verification_status, verification_status: foundUser[0].verification_status,
social_login: foundUser[0].social_login, social_login: foundUser[0].social_login,
social_platform: foundUser[0].social_platform, social_platform: foundUser[0].social_platform,
csrf_k: csrfKey, csrf_k: csrfKey,
more_data: foundUser[0].more_user_data, more_data: foundUser[0].more_user_data,
logged_in_status: true, logged_in_status: true,
date: Date.now(), date: Date.now(),
}; };
if (additionalFields && Array.isArray(additionalFields) && additionalFields.length > 0) { if (additionalFields && Array.isArray(additionalFields) && additionalFields.length > 0) {
additionalFields.forEach((key) => { additionalFields.forEach((key) => {
// @ts-ignore // @ts-ignore
userPayload[key] = foundUser?.[0][key]; userPayload[key] = foundUser?.[0][key];
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** ********************* Send Response */ /** ********************* Send Response */
return { return {
success: true, success: true,
msg: "Login Successful", msg: "Login Successful",
payload: userPayload, payload: userPayload,
userId: "0", userId: "0",
}; };
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in local login-user Request =>", error.message); console.log("Error in local login-user Request =>", error.message);
return { return {
success: false, success: false,
msg: "Login Failed", msg: "Login Failed",
}; };
} }
} }
module.exports = loginLocalUser; module.exports = loginLocalUser;

View File

@ -1,106 +1,106 @@
// @ts-check // @ts-check
const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../engine/utils/varDatabaseDbHandler");
/** /**
* *
* @param {object} param0 * @param {object} param0
* @param {*} param0.existingUser * @param {*} param0.existingUser
* @param {string[]} [param0.additionalFields] * @param {string[]} [param0.additionalFields]
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [param0.dbSchema] * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} [param0.dbSchema]
* @returns * @returns
*/ */
async function localReauthUser({ existingUser, additionalFields, dbSchema }) { async function localReauthUser({ existingUser, additionalFields, dbSchema }) {
try { try {
/** /**
* Grab data * Grab data
* *
* @description Grab data * @description Grab data
*/ */
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
/** /**
* GRAB user * GRAB user
* *
* @description GRAB user * @description GRAB user
*/ */
const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users"); const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users");
let foundUser = let foundUser =
existingUser?.id && existingUser.id.toString().match(/./) existingUser?.id && existingUser.id.toString().match(/./)
? await varDatabaseDbHandler({ ? await varDatabaseDbHandler({
queryString: `SELECT * FROM users WHERE id=?`, queryString: `SELECT * FROM users WHERE id=?`,
queryValuesArray: [existingUser.id], queryValuesArray: [existingUser.id],
database: dbFullName.replace(/[^a-z0-9_]/g, ""), database: dbFullName.replace(/[^a-z0-9_]/g, ""),
tableSchema, tableSchema,
}) })
: null; : null;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (!foundUser || !foundUser[0]) if (!foundUser || !foundUser[0])
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "No user found", msg: "No user found",
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
let csrfKey = Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2); let csrfKey = Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2);
let userPayload = { let userPayload = {
id: foundUser[0].id, id: foundUser[0].id,
first_name: foundUser[0].first_name, first_name: foundUser[0].first_name,
last_name: foundUser[0].last_name, last_name: foundUser[0].last_name,
username: foundUser[0].username, username: foundUser[0].username,
email: foundUser[0].email, email: foundUser[0].email,
phone: foundUser[0].phone, phone: foundUser[0].phone,
social_id: foundUser[0].social_id, social_id: foundUser[0].social_id,
image: foundUser[0].image, image: foundUser[0].image,
image_thumbnail: foundUser[0].image_thumbnail, image_thumbnail: foundUser[0].image_thumbnail,
verification_status: foundUser[0].verification_status, verification_status: foundUser[0].verification_status,
social_login: foundUser[0].social_login, social_login: foundUser[0].social_login,
social_platform: foundUser[0].social_platform, social_platform: foundUser[0].social_platform,
csrf_k: csrfKey, csrf_k: csrfKey,
more_data: foundUser[0].more_user_data, more_data: foundUser[0].more_user_data,
logged_in_status: true, logged_in_status: true,
date: Date.now(), date: Date.now(),
}; };
if (additionalFields && Array.isArray(additionalFields) && additionalFields.length > 0) { if (additionalFields && Array.isArray(additionalFields) && additionalFields.length > 0) {
additionalFields.forEach((key) => { additionalFields.forEach((key) => {
// @ts-ignore // @ts-ignore
userPayload[key] = foundUser?.[0][key]; userPayload[key] = foundUser?.[0][key];
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** ********************* Send Response */ /** ********************* Send Response */
return { return {
success: true, success: true,
msg: "Login Successful", msg: "Login Successful",
payload: userPayload, payload: userPayload,
userId: "0", userId: "0",
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in local login-user Request =>", error.message); console.log("Error in local login-user Request =>", error.message);
return { return {
success: false, success: false,
msg: "Login Failed", msg: "Login Failed",
}; };
} }
} }
module.exports = localReauthUser; module.exports = localReauthUser;

View File

@ -1,134 +1,134 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const encrypt = require("../../../functions/encrypt"); const encrypt = require("../../../functions/encrypt");
const camelJoinedtoCamelSpace = require("../../engine/utils/camelJoinedtoCamelSpace"); const camelJoinedtoCamelSpace = require("../../engine/utils/camelJoinedtoCamelSpace");
const githubLogin = require("./utils/githubLogin"); const githubLogin = require("./utils/githubLogin");
const handleSocialDb = require("./utils/handleSocialDb"); const handleSocialDb = require("./utils/handleSocialDb");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
const database = process.env.DSQL_DB_NAME || ""; const database = process.env.DSQL_DB_NAME || "";
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
/** /**
* SERVER FUNCTION: Login with google Function * SERVER FUNCTION: Login with google Function
* ============================================================================== * ==============================================================================
* *
* @async * @async
* *
* @param {object} params - main params object * @param {object} params - main params object
* @param {http.ServerResponse} params.res - HTTPS response object * @param {http.ServerResponse} params.res - HTTPS response object
* @param {string} params.code * @param {string} params.code
* @param {string} [params.email] * @param {string} [params.email]
* @param {string} params.clientId * @param {string} params.clientId
* @param {string} params.clientSecret * @param {string} params.clientSecret
* @param {object} [params.additionalFields] * @param {object} [params.additionalFields]
* @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema * @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema
*/ */
async function localGithubAuth({ res, code, email, clientId, clientSecret, additionalFields, dbSchema }) { async function localGithubAuth({ res, code, email, clientId, clientSecret, additionalFields, dbSchema }) {
try { try {
/** /**
* User auth * User auth
* *
* @description Authenticate user * @description Authenticate user
*/ */
if (!code || !clientId || !clientSecret) { if (!code || !clientId || !clientSecret) {
return { return {
success: false, success: false,
msg: "Missing query params", msg: "Missing query params",
}; };
} }
if (typeof code !== "string" || typeof clientId !== "string" || typeof clientSecret !== "string" || typeof database !== "string") { if (typeof code !== "string" || typeof clientId !== "string" || typeof clientSecret !== "string" || typeof database !== "string") {
return { return {
success: false, success: false,
msg: "Wrong Parameters", msg: "Wrong Parameters",
}; };
} }
/** /**
* Create new user folder and file * Create new user folder and file
* *
* @description Create new user folder and file * @description Create new user folder and file
*/ */
const gitHubUser = await githubLogin({ const gitHubUser = await githubLogin({
code: code, code: code,
clientId: clientId, clientId: clientId,
clientSecret: clientSecret, clientSecret: clientSecret,
}); });
if (!gitHubUser) { if (!gitHubUser) {
return { return {
success: false, success: false,
msg: "No github user returned", msg: "No github user returned",
}; };
} }
const targetDbName = database; const targetDbName = database;
const socialId = gitHubUser.name || gitHubUser.id || gitHubUser.login; const socialId = gitHubUser.name || gitHubUser.id || gitHubUser.login;
const targetName = gitHubUser.name || gitHubUser.login; const targetName = gitHubUser.name || gitHubUser.login;
const nameArray = targetName?.match(/ /) ? targetName?.split(" ") : targetName?.match(/\-/) ? targetName?.split("-") : [targetName]; const nameArray = targetName?.match(/ /) ? targetName?.split(" ") : targetName?.match(/\-/) ? targetName?.split("-") : [targetName];
const payload = { const payload = {
email: gitHubUser.email, email: gitHubUser.email,
first_name: camelJoinedtoCamelSpace(nameArray[0]) || "", first_name: camelJoinedtoCamelSpace(nameArray[0]) || "",
last_name: camelJoinedtoCamelSpace(nameArray[1]) || "", last_name: camelJoinedtoCamelSpace(nameArray[1]) || "",
social_id: socialId, social_id: socialId,
social_platform: "github", social_platform: "github",
image: gitHubUser.avatar_url, image: gitHubUser.avatar_url,
image_thumbnail: gitHubUser.avatar_url, image_thumbnail: gitHubUser.avatar_url,
username: "github-user-" + socialId, username: "github-user-" + socialId,
}; };
if (additionalFields && Object.keys(additionalFields).length > 0) { if (additionalFields && Object.keys(additionalFields).length > 0) {
Object.keys(additionalFields).forEach((key) => { Object.keys(additionalFields).forEach((key) => {
// @ts-ignore // @ts-ignore
payload[key] = additionalFields[key]; payload[key] = additionalFields[key];
}); });
} }
const loggedInGithubUser = await handleSocialDb({ const loggedInGithubUser = await handleSocialDb({
database: targetDbName, database: targetDbName,
email: gitHubUser.email, email: gitHubUser.email,
payload: payload, payload: payload,
social_platform: "github", social_platform: "github",
res: res, res: res,
social_id: socialId, social_id: socialId,
supEmail: email, supEmail: email,
additionalFields, additionalFields,
dbSchema: dbSchema, dbSchema: dbSchema,
}); });
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
return { ...loggedInGithubUser, dsqlUserId: "0" }; return { ...loggedInGithubUser, dsqlUserId: "0" };
//////////////////////////////////////// ////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("localGithubAuth error", error.message); console.log("localGithubAuth error", error.message);
return { success: false, msg: "Failed!" }; return { success: false, msg: "Failed!" };
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = localGithubAuth; module.exports = localGithubAuth;

View File

@ -1,169 +1,169 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const encrypt = require("../../../functions/encrypt"); const encrypt = require("../../../functions/encrypt");
const decrypt = require("../../../functions/decrypt"); const decrypt = require("../../../functions/decrypt");
const handleSocialDb = require("./utils/handleSocialDb"); const handleSocialDb = require("./utils/handleSocialDb");
const httpsRequest = require("./utils/httpsRequest"); const httpsRequest = require("./utils/httpsRequest");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object | null} FunctionReturn * @typedef {object | null} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {import("../../types/user.td").DATASQUIREL_LoggedInUser | null} user - Returned User * @property {import("../../types/user.td").DATASQUIREL_LoggedInUser | null} user - Returned User
* @property {number} [dsqlUserId] - Dsql User Id * @property {number} [dsqlUserId] - Dsql User Id
* @property {string} [msg] - Response message * @property {string} [msg] - Response message
*/ */
const database = process.env.DSQL_DB_NAME || ""; const database = process.env.DSQL_DB_NAME || "";
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
/** /**
* SERVER FUNCTION: Login with google Function * SERVER FUNCTION: Login with google Function
* ============================================================================== * ==============================================================================
* *
* @async * @async
* *
* @param {object} params - main params object * @param {object} params - main params object
* @param {string} params.token - Google access token gotten from the client side * @param {string} params.token - Google access token gotten from the client side
* @param {string} params.clientId - Google client id * @param {string} params.clientId - Google client id
* @param {http.ServerResponse} params.response - HTTPS response object * @param {http.ServerResponse} params.response - HTTPS response object
* @param {object} [params.additionalFields] - Additional Fields to be added to the user object * @param {object} [params.additionalFields] - Additional Fields to be added to the user object
* @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Database Schema * @param {import("../../../types/database-schema.td").DSQL_DatabaseSchemaType} [params.dbSchema] - Database Schema
* *
* @returns { Promise<FunctionReturn> } * @returns { Promise<FunctionReturn> }
*/ */
async function localGoogleAuth({ dbSchema, token, clientId, response, additionalFields }) { async function localGoogleAuth({ dbSchema, token, clientId, response, additionalFields }) {
/** /**
* Send Response * Send Response
* *
* @description Send a boolean response * @description Send a boolean response
*/ */
try { try {
/** /**
* Grab User data * Grab User data
* *
* @description Grab User data * @description Grab User data
* @type {{ success: boolean, payload: any, msg: string }} * @type {{ success: boolean, payload: any, msg: string }}
*/ */
const payloadResponse = await httpsRequest({ const payloadResponse = await httpsRequest({
method: "POST", method: "POST",
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: "/user/grab-google-user-from-token", path: "/user/grab-google-user-from-token",
body: { body: {
token: token, token: token,
clientId: clientId, clientId: clientId,
}, },
headers: { headers: {
Authorization: process.env.DSQL_API_KEY, Authorization: process.env.DSQL_API_KEY,
}, },
}); });
const payload = payloadResponse.payload; const payload = payloadResponse.payload;
if (!payloadResponse.success || !payload) { if (!payloadResponse.success || !payload) {
console.log("payloadResponse Failed =>", payloadResponse); console.log("payloadResponse Failed =>", payloadResponse);
return { return {
success: false, success: false,
msg: "User fetch Error", msg: "User fetch Error",
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
if (!database || typeof database != "string" || database?.match(/ /)) { if (!database || typeof database != "string" || database?.match(/ /)) {
return { return {
success: false, success: false,
user: undefined, user: undefined,
msg: "Please provide a database slug(database name in lowercase with no spaces)", msg: "Please provide a database slug(database name in lowercase with no spaces)",
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Create new user folder and file * Create new user folder and file
* *
* @description Create new user folder and file * @description Create new user folder and file
*/ */
const targetDbName = database; const targetDbName = database;
if (!payload) { if (!payload) {
return { return {
success: false, success: false,
msg: "No payload", msg: "No payload",
}; };
} }
const { given_name, family_name, email, sub, picture, email_verified } = payload; const { given_name, family_name, email, sub, picture, email_verified } = payload;
const payloadObject = { const payloadObject = {
email: email || "", email: email || "",
first_name: given_name || "", first_name: given_name || "",
last_name: family_name || "", last_name: family_name || "",
social_id: sub, social_id: sub,
social_platform: "google", social_platform: "google",
image: picture || "", image: picture || "",
image_thumbnail: picture || "", image_thumbnail: picture || "",
username: `google-user-${sub}`, username: `google-user-${sub}`,
}; };
if (additionalFields && Object.keys(additionalFields).length > 0) { if (additionalFields && Object.keys(additionalFields).length > 0) {
Object.keys(additionalFields).forEach((key) => { Object.keys(additionalFields).forEach((key) => {
// @ts-ignore // @ts-ignore
payloadObject[key] = additionalFields[key]; payloadObject[key] = additionalFields[key];
}); });
} }
const loggedInGoogleUser = await handleSocialDb({ const loggedInGoogleUser = await handleSocialDb({
database: targetDbName, database: targetDbName,
email: email || "", email: email || "",
payload: payloadObject, payload: payloadObject,
social_platform: "google", social_platform: "google",
res: response, res: response,
social_id: sub, social_id: sub,
additionalFields, additionalFields,
dbSchema, dbSchema,
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return { ...loggedInGoogleUser, dsqlUserId: "0" }; return { ...loggedInGoogleUser, dsqlUserId: "0" };
//////////////////////////////////////// ////////////////////////////////////////
} catch (error) { } catch (error) {
return { return {
success: false, success: false,
msg: "User fetch Error", msg: "User fetch Error",
}; };
//////////////////////////////////////// ////////////////////////////////////////
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = localGoogleAuth; module.exports = localGoogleAuth;

View File

@ -1,164 +1,164 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const fs = require("fs"); const fs = require("fs");
const httpsRequest = require("./httpsRequest"); const httpsRequest = require("./httpsRequest");
const dbHandler = require("../../../engine/utils/dbHandler"); const dbHandler = require("../../../engine/utils/dbHandler");
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
/** /**
* *
* @typedef {object} GithubUserPayload * @typedef {object} GithubUserPayload
* @property {string} login - Full name merged eg. "JohnDoe" * @property {string} login - Full name merged eg. "JohnDoe"
* @property {number} id - github user id * @property {number} id - github user id
* @property {string} node_id - Some other id * @property {string} node_id - Some other id
* @property {string} avatar_url - profile picture * @property {string} avatar_url - profile picture
* @property {string} gravatar_id - some other id * @property {string} gravatar_id - some other id
* @property {string} url - Github user URL * @property {string} url - Github user URL
* @property {string} html_url - User html URL - whatever that means * @property {string} html_url - User html URL - whatever that means
* @property {string} followers_url - Followers URL * @property {string} followers_url - Followers URL
* @property {string} following_url - Following URL * @property {string} following_url - Following URL
* @property {string} gists_url - Gists URL * @property {string} gists_url - Gists URL
* @property {string} starred_url - Starred URL * @property {string} starred_url - Starred URL
* @property {string} subscriptions_url - Subscriptions URL * @property {string} subscriptions_url - Subscriptions URL
* @property {string} organizations_url - Organizations URL * @property {string} organizations_url - Organizations URL
* @property {string} repos_url - Repositories URL * @property {string} repos_url - Repositories URL
* @property {string} received_events_url - Received Events URL * @property {string} received_events_url - Received Events URL
* @property {string} type - Common value => "User" * @property {string} type - Common value => "User"
* @property {boolean} site_admin - Is site admin or not? Boolean * @property {boolean} site_admin - Is site admin or not? Boolean
* @property {string} name - More like "username" * @property {string} name - More like "username"
* @property {string} company - User company * @property {string} company - User company
* @property {string} blog - User blog URL * @property {string} blog - User blog URL
* @property {string} location - User Location * @property {string} location - User Location
* @property {string} email - User Email * @property {string} email - User Email
* @property {string} hireable - Is user hireable * @property {string} hireable - Is user hireable
* @property {string} bio - User bio * @property {string} bio - User bio
* @property {string} twitter_username - User twitter username * @property {string} twitter_username - User twitter username
* @property {number} public_repos - Number of public repositories * @property {number} public_repos - Number of public repositories
* @property {number} public_gists - Number of public gists * @property {number} public_gists - Number of public gists
* @property {number} followers - Number of followers * @property {number} followers - Number of followers
* @property {number} following - Number of following * @property {number} following - Number of following
* @property {string} created_at - Date created * @property {string} created_at - Date created
* @property {string} updated_at - Date updated * @property {string} updated_at - Date updated
*/ */
/** /**
* Login/signup a github user * Login/signup a github user
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - foundUser if any * @param {Object} params - foundUser if any
* @param {string} params.code - github auth token * @param {string} params.code - github auth token
* @param {string} params.clientId - github client Id * @param {string} params.clientId - github client Id
* @param {string} params.clientSecret - github client Secret * @param {string} params.clientSecret - github client Secret
* *
* @returns {Promise<GithubUserPayload|null>} * @returns {Promise<GithubUserPayload|null>}
*/ */
async function githubLogin({ code, clientId, clientSecret }) { async function githubLogin({ code, clientId, clientSecret }) {
/** @type {GithubUserPayload | null} */ /** @type {GithubUserPayload | null} */
let gitHubUser = null; let gitHubUser = null;
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
try { try {
/** /**
* Create new user folder and file * Create new user folder and file
* *
* @description Create new user folder and file * @description Create new user folder and file
*/ */
// const response = await fetch(`https://github.com/login/oauth/access_token?client_id=${process.env.GITHUB_ID}`); // const response = await fetch(`https://github.com/login/oauth/access_token?client_id=${process.env.GITHUB_ID}`);
const response = await httpsRequest({ const response = await httpsRequest({
method: "POST", method: "POST",
hostname: "github.com", hostname: "github.com",
path: `/login/oauth/access_token?client_id=${clientId}&client_secret=${clientSecret}&code=${code}`, path: `/login/oauth/access_token?client_id=${clientId}&client_secret=${clientSecret}&code=${code}`,
headers: { headers: {
Accept: "application/json", Accept: "application/json",
"User-Agent": "*", "User-Agent": "*",
}, },
}); });
// `https://github.com/login/oauth/access_token?client_id=${process.env.GITHUB_ID}&client_secret=${process.env.GITHUB_SECRET}&code=${code}`, // `https://github.com/login/oauth/access_token?client_id=${process.env.GITHUB_ID}&client_secret=${process.env.GITHUB_SECRET}&code=${code}`,
// body: JSON.stringify({ // body: JSON.stringify({
// client_id: process.env.GITHUB_ID, // client_id: process.env.GITHUB_ID,
// client_secret: process.env.GITHUB_SECRET, // client_secret: process.env.GITHUB_SECRET,
// code: code, // code: code,
// }), // }),
const accessTokenObject = JSON.parse(response); const accessTokenObject = JSON.parse(response);
if (!accessTokenObject?.access_token) { if (!accessTokenObject?.access_token) {
return gitHubUser; return gitHubUser;
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
const userDataResponse = await httpsRequest({ const userDataResponse = await httpsRequest({
method: "GET", method: "GET",
hostname: "api.github.com", hostname: "api.github.com",
path: "/user", path: "/user",
headers: { headers: {
Authorization: `Bearer ${accessTokenObject.access_token}`, Authorization: `Bearer ${accessTokenObject.access_token}`,
"User-Agent": "*", "User-Agent": "*",
}, },
}); });
gitHubUser = JSON.parse(userDataResponse); gitHubUser = JSON.parse(userDataResponse);
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
if (!gitHubUser?.email) { if (!gitHubUser?.email) {
const existingGithubUser = await dbHandler({ const existingGithubUser = await dbHandler({
query: `SELECT email FROM users WHERE social_login='1' AND social_platform='github' AND social_id= ?`, query: `SELECT email FROM users WHERE social_login='1' AND social_platform='github' AND social_id= ?`,
values: [gitHubUser?.id || ""], values: [gitHubUser?.id || ""],
}); });
if (existingGithubUser && existingGithubUser[0] && gitHubUser) { if (existingGithubUser && existingGithubUser[0] && gitHubUser) {
gitHubUser.email = existingGithubUser[0].email; gitHubUser.email = existingGithubUser[0].email;
} }
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
console.log("ERROR in githubLogin.js backend function =>", error.message); console.log("ERROR in githubLogin.js backend function =>", error.message);
// serverError({ // serverError({
// component: "/api/social-login/github-auth/catch-error", // component: "/api/social-login/github-auth/catch-error",
// message: error.message, // message: error.message,
// user: user, // user: user,
// }); // });
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
return gitHubUser; return gitHubUser;
} }
module.exports = githubLogin; module.exports = githubLogin;

View File

@ -1,376 +1,376 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const fs = require("fs"); const fs = require("fs");
const http = require("http"); const http = require("http");
const varDatabaseDbHandler = require("../../../engine/utils/varDatabaseDbHandler"); const varDatabaseDbHandler = require("../../../engine/utils/varDatabaseDbHandler");
const addDbEntry = require("../../../query/utils/addDbEntry"); const addDbEntry = require("../../../query/utils/addDbEntry");
const encrypt = require("../../../../functions/encrypt"); const encrypt = require("../../../../functions/encrypt");
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
/** /**
* @typedef {object} FunctionReturn * @typedef {object} FunctionReturn
* @property {boolean} success - Did the operation complete successfully or not? * @property {boolean} success - Did the operation complete successfully or not?
* @property {{ * @property {{
* id: number, * id: number,
* first_name: string, * first_name: string,
* last_name: string, * last_name: string,
* }|null} user - User payload object: or "null" * }|null} user - User payload object: or "null"
* @property {string} [msg] - Message * @property {string} [msg] - Message
* @property {string} [error] - Error Message * @property {string} [error] - Error Message
* @property {string | number} [social_id] - Social Id * @property {string | number} [social_id] - Social Id
* @property {string} [social_platform] - Social Platform * @property {string} [social_platform] - Social Platform
* @property {object} [payload] - Payload * @property {object} [payload] - Payload
* @property {boolean} [alert] - Alert * @property {boolean} [alert] - Alert
* @property {*} [newUser] - New User * @property {*} [newUser] - New User
*/ */
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
const database = process.env.DSQL_DB_NAME || ""; const database = process.env.DSQL_DB_NAME || "";
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
/** /**
* Handle Social User Auth on Datasquirel Database * Handle Social User Auth on Datasquirel Database
* ============================================================================== * ==============================================================================
* *
* @description This function handles all social login logic after the social user * @description This function handles all social login logic after the social user
* has been authenticated and userpayload is present. The payload MUST contain the * has been authenticated and userpayload is present. The payload MUST contain the
* specified fields because this funciton will create a new user if the authenticated * specified fields because this funciton will create a new user if the authenticated
* user does not exist. * user does not exist.
* *
* @param {{ * @param {{
* database: string|null|undefined, * database: string|null|undefined,
* social_id: string|number, * social_id: string|number,
* email: string, * email: string,
* social_platform: string, * social_platform: string,
* payload: { * payload: {
* social_id: string | number, * social_id: string | number,
* email: string, * email: string,
* social_platform: string, * social_platform: string,
* first_name: string, * first_name: string,
* last_name: string, * last_name: string,
* image: string, * image: string,
* image_thumbnail: string, * image_thumbnail: string,
* username: string, * username: string,
* }, * },
* res: http.ServerResponse, * res: http.ServerResponse,
* supEmail?: string | null, * supEmail?: string | null,
* additionalFields?: object, * additionalFields?: object,
* dbSchema: import("../../../../types/database-schema.td").DSQL_DatabaseSchemaType | undefined * dbSchema: import("../../../../types/database-schema.td").DSQL_DatabaseSchemaType | undefined
* }} params - function parameters inside an object * }} params - function parameters inside an object
* *
* @returns {Promise<FunctionReturn>} - Response object * @returns {Promise<FunctionReturn>} - Response object
*/ */
async function handleSocialDb({ social_id, email, social_platform, payload, res, supEmail, additionalFields, dbSchema }) { async function handleSocialDb({ social_id, email, social_platform, payload, res, supEmail, additionalFields, dbSchema }) {
const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users"); const tableSchema = dbSchema?.tables.find((tb) => tb?.tableName === "users");
try { try {
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
let existingSocialIdUser = await varDatabaseDbHandler({ let existingSocialIdUser = await varDatabaseDbHandler({
database: database ? database : "datasquirel", database: database ? database : "datasquirel",
queryString: `SELECT * FROM users WHERE social_id = ? AND social_login='1' AND social_platform = ? `, queryString: `SELECT * FROM users WHERE social_id = ? AND social_login='1' AND social_platform = ? `,
queryValuesArray: [social_id.toString(), social_platform], queryValuesArray: [social_id.toString(), social_platform],
}); });
if (existingSocialIdUser && existingSocialIdUser[0]) { if (existingSocialIdUser && existingSocialIdUser[0]) {
return await loginSocialUser({ return await loginSocialUser({
user: existingSocialIdUser[0], user: existingSocialIdUser[0],
social_platform, social_platform,
res, res,
database, database,
additionalFields, additionalFields,
}); });
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
const finalEmail = email ? email : supEmail ? supEmail : null; const finalEmail = email ? email : supEmail ? supEmail : null;
if (!finalEmail) { if (!finalEmail) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "No Email Present", msg: "No Email Present",
social_id, social_id,
social_platform, social_platform,
payload, payload,
}; };
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
let existingEmailOnly = await varDatabaseDbHandler({ let existingEmailOnly = await varDatabaseDbHandler({
database: database ? database : "datasquirel", database: database ? database : "datasquirel",
queryString: `SELECT * FROM users WHERE email = ?`, queryString: `SELECT * FROM users WHERE email = ?`,
queryValuesArray: [finalEmail], queryValuesArray: [finalEmail],
tableSchema, tableSchema,
}); });
if (existingEmailOnly && existingEmailOnly[0]) { if (existingEmailOnly && existingEmailOnly[0]) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "This Email is already taken", msg: "This Email is already taken",
alert: true, alert: true,
}; };
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
const foundUser = await varDatabaseDbHandler({ const foundUser = await varDatabaseDbHandler({
database: database ? database : "datasquirel", database: database ? database : "datasquirel",
queryString: `SELECT * FROM users WHERE email='${finalEmail}' AND social_login='1' AND social_platform='${social_platform}' AND social_id='${social_id}'`, queryString: `SELECT * FROM users WHERE email='${finalEmail}' AND social_login='1' AND social_platform='${social_platform}' AND social_id='${social_id}'`,
}); });
if (foundUser && foundUser[0]) { if (foundUser && foundUser[0]) {
return await loginSocialUser({ return await loginSocialUser({
user: payload, user: payload,
social_platform, social_platform,
res, res,
database, database,
additionalFields, additionalFields,
}); });
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
const socialHashedPassword = encrypt({ const socialHashedPassword = encrypt({
data: social_id.toString(), data: social_id.toString(),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
const data = { const data = {
social_login: "1", social_login: "1",
verification_status: supEmail ? "0" : "1", verification_status: supEmail ? "0" : "1",
password: socialHashedPassword, password: socialHashedPassword,
}; };
Object.keys(payload).forEach((key) => { Object.keys(payload).forEach((key) => {
// @ts-ignore // @ts-ignore
data[key] = payload[key]; data[key] = payload[key];
}); });
const newUser = await addDbEntry({ const newUser = await addDbEntry({
dbFullName: database ? database : "datasquirel", dbFullName: database ? database : "datasquirel",
tableName: "users", tableName: "users",
duplicateColumnName: "email", duplicateColumnName: "email",
duplicateColumnValue: finalEmail, duplicateColumnValue: finalEmail,
data: { data: {
...data, ...data,
email: finalEmail, email: finalEmail,
}, },
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
tableSchema, tableSchema,
}); });
if (newUser?.insertId) { if (newUser?.insertId) {
const newUserQueried = await varDatabaseDbHandler({ const newUserQueried = await varDatabaseDbHandler({
database: database ? database : "datasquirel", database: database ? database : "datasquirel",
queryString: `SELECT * FROM users WHERE id='${newUser.insertId}'`, queryString: `SELECT * FROM users WHERE id='${newUser.insertId}'`,
}); });
if (!newUserQueried || !newUserQueried[0]) if (!newUserQueried || !newUserQueried[0])
return { return {
success: false, success: false,
user: null, user: null,
msg: "User Insertion Failed!", msg: "User Insertion Failed!",
}; };
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
if (supEmail && database?.match(/^datasquirel$/)) { if (supEmail && database?.match(/^datasquirel$/)) {
/** /**
* Send email Verification * Send email Verification
* *
* @description Send verification email to newly created agent * @description Send verification email to newly created agent
*/ */
let generatedToken = encrypt({ let generatedToken = encrypt({
data: JSON.stringify({ data: JSON.stringify({
id: newUser.insertId, id: newUser.insertId,
email: supEmail, email: supEmail,
dateCode: Date.now(), dateCode: Date.now(),
}), }),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
return await loginSocialUser({ return await loginSocialUser({
user: newUserQueried[0], user: newUserQueried[0],
social_platform, social_platform,
res, res,
database, database,
additionalFields, additionalFields,
}); });
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
} else { } else {
console.log("Social User Failed to insert in 'handleSocialDb.js' backend function =>", newUser); console.log("Social User Failed to insert in 'handleSocialDb.js' backend function =>", newUser);
return { return {
success: false, success: false,
user: null, user: null,
msg: "Social User Failed to insert in 'handleSocialDb.js' backend function => ", msg: "Social User Failed to insert in 'handleSocialDb.js' backend function => ",
newUser: newUser, newUser: newUser,
}; };
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("ERROR in 'handleSocialDb.js' backend function =>", error.message); console.log("ERROR in 'handleSocialDb.js' backend function =>", error.message);
return { return {
success: false, success: false,
user: null, user: null,
error: error.message, error: error.message,
}; };
// serverError({ // serverError({
// component: "/functions/backend/social-login/handleSocialDb.js - main-catch-error", // component: "/functions/backend/social-login/handleSocialDb.js - main-catch-error",
// message: error.message, // message: error.message,
// user: { first_name, last_name }, // user: { first_name, last_name },
// }); // });
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
} }
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
/** /**
* Function to login social user * Function to login social user
* ============================================================================== * ==============================================================================
* @description This function logs in the user after 'handleSocialDb' function finishes * @description This function logs in the user after 'handleSocialDb' function finishes
* the user creation or confirmation process * the user creation or confirmation process
* *
* @async * @async
* *
* @param {object} params - function parameters inside an object * @param {object} params - function parameters inside an object
* @param {{ * @param {{
* first_name: string, * first_name: string,
* last_name: string, * last_name: string,
* email: string, * email: string,
* social_id: string|number, * social_id: string|number,
* }} params.user - user object * }} params.user - user object
* @param {string} params.social_platform - Whether its "google" or "facebook" or "github" * @param {string} params.social_platform - Whether its "google" or "facebook" or "github"
* @param {http.ServerResponse} params.res - Https response object * @param {http.ServerResponse} params.res - Https response object
* @param {string|null} params.database - Target Database * @param {string|null} params.database - Target Database
* @param {object} [params.additionalFields] - Additional fields to be added to the user payload * @param {object} [params.additionalFields] - Additional fields to be added to the user payload
* *
* @returns {Promise<{ * @returns {Promise<{
* success: boolean, * success: boolean,
* user: { id: number, first_name: string, last_name: string } | null * user: { id: number, first_name: string, last_name: string } | null
* msg?: string * msg?: string
* }>} * }>}
*/ */
async function loginSocialUser({ user, social_platform, res, database, additionalFields }) { async function loginSocialUser({ user, social_platform, res, database, additionalFields }) {
const foundUser = await varDatabaseDbHandler({ const foundUser = await varDatabaseDbHandler({
database: database ? database : "datasquirel", database: database ? database : "datasquirel",
queryString: `SELECT * FROM users WHERE email='${user.email}' AND social_id='${user.social_id}' AND social_platform='${social_platform}'`, queryString: `SELECT * FROM users WHERE email='${user.email}' AND social_id='${user.social_id}' AND social_platform='${social_platform}'`,
}); });
let csrfKey = Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2); let csrfKey = Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2);
if (!foundUser?.[0]) { if (!foundUser?.[0]) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "User Not Found", msg: "User Not Found",
}; };
} }
let userPayload = { let userPayload = {
id: foundUser[0].id, id: foundUser[0].id,
type: foundUser[0].type || "", type: foundUser[0].type || "",
stripe_id: foundUser[0].stripe_id || "", stripe_id: foundUser[0].stripe_id || "",
first_name: foundUser[0].first_name, first_name: foundUser[0].first_name,
last_name: foundUser[0].last_name, last_name: foundUser[0].last_name,
username: foundUser[0].username, username: foundUser[0].username,
email: foundUser[0].email, email: foundUser[0].email,
social_id: foundUser[0].social_id, social_id: foundUser[0].social_id,
image: foundUser[0].image, image: foundUser[0].image,
image_thumbnail: foundUser[0].image_thumbnail, image_thumbnail: foundUser[0].image_thumbnail,
verification_status: foundUser[0].verification_status, verification_status: foundUser[0].verification_status,
social_login: foundUser[0].social_login, social_login: foundUser[0].social_login,
social_platform: foundUser[0].social_platform, social_platform: foundUser[0].social_platform,
csrf_k: csrfKey, csrf_k: csrfKey,
logged_in_status: true, logged_in_status: true,
date: Date.now(), date: Date.now(),
}; };
if (additionalFields && Object.keys(additionalFields).length > 0) { if (additionalFields && Object.keys(additionalFields).length > 0) {
Object.keys(additionalFields).forEach((key) => { Object.keys(additionalFields).forEach((key) => {
// @ts-ignore // @ts-ignore
userPayload[key] = foundUser[0][key]; userPayload[key] = foundUser[0][key];
}); });
} }
let encryptedPayload = encrypt({ let encryptedPayload = encrypt({
data: JSON.stringify(userPayload), data: JSON.stringify(userPayload),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
if (res?.setHeader) { if (res?.setHeader) {
res.setHeader("Set-Cookie", [`datasquirelAuthKey=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `csrf=${csrfKey};samesite=strict;path=/;HttpOnly=true`]); res.setHeader("Set-Cookie", [`datasquirelAuthKey=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `csrf=${csrfKey};samesite=strict;path=/;HttpOnly=true`]);
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
return { return {
success: true, success: true,
user: userPayload, user: userPayload,
}; };
} }
module.exports = handleSocialDb; module.exports = handleSocialDb;

View File

@ -1,105 +1,105 @@
/** /**
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
/** /**
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @param {{ * @param {{
* url?: string, * url?: string,
* method: string, * method: string,
* hostname: string, * hostname: string,
* path?: string, * path?: string,
* href?: string, * href?: string,
* headers?: object, * headers?: object,
* body?: object, * body?: object,
* }} params - params * }} params - params
*/ */
function httpsRequest({ url, method, hostname, path, href, headers, body }) { function httpsRequest({ url, method, hostname, path, href, headers, body }) {
const reqPayloadString = body ? JSON.stringify(body) : null; const reqPayloadString = body ? JSON.stringify(body) : null;
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
let requestOptions = { let requestOptions = {
method: method, method: method,
hostname: hostname, hostname: hostname,
port: 443, port: 443,
headers: {}, headers: {},
}; };
if (path) requestOptions.path = path; if (path) requestOptions.path = path;
if (href) requestOptions.href = href; if (href) requestOptions.href = href;
if (headers) requestOptions.headers = headers; if (headers) requestOptions.headers = headers;
if (body) { if (body) {
requestOptions.headers["Content-Type"] = "application/json"; requestOptions.headers["Content-Type"] = "application/json";
requestOptions.headers["Content-Length"] = Buffer.from(reqPayloadString || "").length; requestOptions.headers["Content-Length"] = Buffer.from(reqPayloadString || "").length;
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
return new Promise((res, rej) => { return new Promise((res, rej) => {
const httpsRequest = https.request( const httpsRequest = https.request(
/* ====== Request Options object ====== */ /* ====== Request Options object ====== */
// @ts-ignore // @ts-ignore
url ? url : requestOptions, url ? url : requestOptions,
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
/* ====== Callback function ====== */ /* ====== Callback function ====== */
(response) => { (response) => {
var str = ""; var str = "";
// ## another chunk of data has been received, so append it to `str` // ## another chunk of data has been received, so append it to `str`
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
// ## the whole response has been received, so we just print it out here // ## the whole response has been received, so we just print it out here
response.on("end", function () { response.on("end", function () {
res(str); res(str);
}); });
response.on("error", (error) => { response.on("error", (error) => {
console.log("HTTP response error =>", error.message); console.log("HTTP response error =>", error.message);
}); });
} }
); );
if (body) httpsRequest.write(reqPayloadString); if (body) httpsRequest.write(reqPayloadString);
httpsRequest.on("error", (error) => { httpsRequest.on("error", (error) => {
console.log("HTTPS request ERROR =>", error); console.log("HTTPS request ERROR =>", error);
}); });
httpsRequest.end(); httpsRequest.end();
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
//////////////////////////////////////////////// ////////////////////////////////////////////////
}); });
} }
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
module.exports = httpsRequest; module.exports = httpsRequest;

View File

@ -1,85 +1,85 @@
// @ts-check // @ts-check
const updateDbEntry = require("../query/utils/updateDbEntry"); const updateDbEntry = require("../query/utils/updateDbEntry");
/** /**
* @typedef {Object} LocalPostReturn * @typedef {Object} LocalPostReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {*} [payload] - GET request results * @property {*} [payload] - GET request results
* @property {string} [msg] - Message * @property {string} [msg] - Message
* @property {string} [error] - Error Message * @property {string} [error] - Error Message
*/ */
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {*} params.payload - SQL Query * @param {*} params.payload - SQL Query
* @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema - Name of the table to query * @param {import("../../types/database-schema.td").DSQL_DatabaseSchemaType} params.dbSchema - Name of the table to query
* *
* @returns { Promise<LocalPostReturn> } - Return Object * @returns { Promise<LocalPostReturn> } - Return Object
*/ */
async function localUpdateUser({ payload, dbSchema }) { async function localUpdateUser({ payload, dbSchema }) {
try { try {
/** /**
* User auth * User auth
* *
* @description Authenticate user * @description Authenticate user
*/ */
/** /**
* Initialize Variables * Initialize Variables
*/ */
const dbFullName = process.env.DSQL_DB_NAME || ""; const dbFullName = process.env.DSQL_DB_NAME || "";
const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || ""; const encryptionKey = process.env.DSQL_ENCRYPTION_KEY || "";
const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || ""; const encryptionSalt = process.env.DSQL_ENCRYPTION_SALT || "";
const data = (() => { const data = (() => {
const reqBodyKeys = Object.keys(payload); const reqBodyKeys = Object.keys(payload);
const finalData = {}; const finalData = {};
reqBodyKeys.forEach((key) => { reqBodyKeys.forEach((key) => {
if (key?.match(/^date_|^id$/)) return; if (key?.match(/^date_|^id$/)) return;
// @ts-ignore // @ts-ignore
finalData[key] = payload[key]; finalData[key] = payload[key];
}); });
return finalData; return finalData;
})(); })();
const tableSchema = dbSchema.tables.find((tb) => tb?.tableName === "users"); const tableSchema = dbSchema.tables.find((tb) => tb?.tableName === "users");
const updateUser = await updateDbEntry({ const updateUser = await updateDbEntry({
dbContext: "Dsql User", dbContext: "Dsql User",
paradigm: "Full Access", paradigm: "Full Access",
dbFullName: dbFullName, dbFullName: dbFullName,
tableName: "users", tableName: "users",
identifierColumnName: "id", identifierColumnName: "id",
identifierValue: payload.id, identifierValue: payload.id,
data: data, data: data,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
tableSchema, tableSchema,
}); });
return { return {
success: true, success: true,
payload: updateUser, payload: updateUser,
}; };
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
//////////////////////////////////////// ////////////////////////////////////////
console.log("Error in local add-user Request =>", error.message); console.log("Error in local add-user Request =>", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Something went wrong!", msg: "Something went wrong!",
}; };
//////////////////////////////////////// ////////////////////////////////////////
} }
} }
module.exports = localUpdateUser; module.exports = localUpdateUser;

View File

@ -1,46 +1,46 @@
// @ts-check // @ts-check
const { scryptSync, createDecipheriv } = require("crypto"); const { scryptSync, createDecipheriv } = require("crypto");
const { Buffer } = require("buffer"); const { Buffer } = require("buffer");
/** /**
* *
* @param {object} param0 * @param {object} param0
* @param {string} param0.encryptedString * @param {string} param0.encryptedString
* @param {string} param0.encryptionKey * @param {string} param0.encryptionKey
* @param {string} param0.encryptionSalt * @param {string} param0.encryptionSalt
* @returns * @returns
*/ */
const decrypt = ({ encryptedString, encryptionKey, encryptionSalt }) => { const decrypt = ({ encryptedString, encryptionKey, encryptionSalt }) => {
if (!encryptedString?.match(/./)) { if (!encryptedString?.match(/./)) {
console.log("Encrypted string is invalid"); console.log("Encrypted string is invalid");
return encryptedString; return encryptedString;
} }
if (!encryptionKey?.match(/.{8,}/)) { if (!encryptionKey?.match(/.{8,}/)) {
console.log("Decrption key is invalid"); console.log("Decrption key is invalid");
return encryptedString; return encryptedString;
} }
if (!encryptionSalt?.match(/.{8,}/)) { if (!encryptionSalt?.match(/.{8,}/)) {
console.log("Decrption salt is invalid"); console.log("Decrption salt is invalid");
return encryptedString; return encryptedString;
} }
const algorithm = "aes-192-cbc"; const algorithm = "aes-192-cbc";
let key = scryptSync(encryptionKey, encryptionSalt, 24); let key = scryptSync(encryptionKey, encryptionSalt, 24);
let iv = Buffer.alloc(16, 0); let iv = Buffer.alloc(16, 0);
const decipher = createDecipheriv(algorithm, key, iv); const decipher = createDecipheriv(algorithm, key, iv);
try { try {
let decrypted = decipher.update(encryptedString, "hex", "utf8"); let decrypted = decipher.update(encryptedString, "hex", "utf8");
decrypted += decipher.final("utf8"); decrypted += decipher.final("utf8");
return decrypted; return decrypted;
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in decrypting =>", error.message); console.log("Error in decrypting =>", error.message);
return encryptedString; return encryptedString;
} }
}; };
module.exports = decrypt; module.exports = decrypt;

View File

@ -1,45 +1,45 @@
// @ts-check // @ts-check
const { scryptSync, createCipheriv } = require("crypto"); const { scryptSync, createCipheriv } = require("crypto");
const { Buffer } = require("buffer"); const { Buffer } = require("buffer");
/** /**
* *
* @param {object} param0 * @param {object} param0
* @param {string} param0.data * @param {string} param0.data
* @param {string} param0.encryptionKey * @param {string} param0.encryptionKey
* @param {string} param0.encryptionSalt * @param {string} param0.encryptionSalt
* @returns {string | null} * @returns {string | null}
*/ */
const encrypt = ({ data, encryptionKey, encryptionSalt }) => { const encrypt = ({ data, encryptionKey, encryptionSalt }) => {
if (!data?.match(/./)) { if (!data?.match(/./)) {
console.log("Encryption string is invalid"); console.log("Encryption string is invalid");
return data; return data;
} }
if (!encryptionKey?.match(/.{8,}/)) { if (!encryptionKey?.match(/.{8,}/)) {
console.log("Encryption key is invalid"); console.log("Encryption key is invalid");
return data; return data;
} }
if (!encryptionSalt?.match(/.{8,}/)) { if (!encryptionSalt?.match(/.{8,}/)) {
console.log("Encryption salt is invalid"); console.log("Encryption salt is invalid");
return data; return data;
} }
const algorithm = "aes-192-cbc"; const algorithm = "aes-192-cbc";
const password = encryptionKey; const password = encryptionKey;
let key = scryptSync(password, encryptionSalt, 24); let key = scryptSync(password, encryptionSalt, 24);
let iv = Buffer.alloc(16, 0); let iv = Buffer.alloc(16, 0);
const cipher = createCipheriv(algorithm, key, iv); const cipher = createCipheriv(algorithm, key, iv);
try { try {
let encrypted = cipher.update(data, "utf8", "hex"); let encrypted = cipher.update(data, "utf8", "hex");
encrypted += cipher.final("hex"); encrypted += cipher.final("hex");
return encrypted; return encrypted;
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
console.log("Error in encrypting =>", error.message); console.log("Error in encrypting =>", error.message);
return data; return data;
} }
}; };
module.exports = encrypt; module.exports = encrypt;

View File

@ -1,27 +1,27 @@
/** # MODULE TRACE /** # MODULE TRACE
====================================================================== ======================================================================
* Detected 4 files that call this module. The files are listed below: * Detected 4 files that call this module. The files are listed below:
====================================================================== ======================================================================
* `require` Statement Found in [add-user.js] => file:///d:\GitHub\dsql\engine\user\add-user.js * `require` Statement Found in [add-user.js] => file:///d:\GitHub\dsql\engine\user\add-user.js
* `require` Statement Found in [login-user.js] => file:///d:\GitHub\dsql\engine\user\login-user.js * `require` Statement Found in [login-user.js] => file:///d:\GitHub\dsql\engine\user\login-user.js
* `require` Statement Found in [googleLogin.js] => file:///d:\GitHub\dsql\engine\user\social\utils\googleLogin.js * `require` Statement Found in [googleLogin.js] => file:///d:\GitHub\dsql\engine\user\social\utils\googleLogin.js
* `require` Statement Found in [update-user.js] => file:///d:\GitHub\dsql\engine\user\update-user.js * `require` Statement Found in [update-user.js] => file:///d:\GitHub\dsql\engine\user\update-user.js
==== MODULE TRACE END ==== */ ==== MODULE TRACE END ==== */
// @ts-check // @ts-check
const { createHmac } = require("crypto"); const { createHmac } = require("crypto");
/** /**
* # Hash password Function * # Hash password Function
* @param {object} param0 * @param {object} param0
* @param {string} param0.password - Password to hash * @param {string} param0.password - Password to hash
* @param {string} param0.encryptionKey - Encryption key * @param {string} param0.encryptionKey - Encryption key
* @returns {string} * @returns {string}
*/ */
module.exports = function hashPassword({ password, encryptionKey }) { module.exports = function hashPassword({ password, encryptionKey }) {
const hmac = createHmac("sha512", encryptionKey); const hmac = createHmac("sha512", encryptionKey);
hmac.update(password); hmac.update(password);
let hashed = hmac.digest("base64"); let hashed = hmac.digest("base64");
return hashed; return hashed;
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "datasquirel", "name": "datasquirel",
"version": "1.9.0", "version": "1.9.2",
"description": "Cloud-based SQL data management tool", "description": "Cloud-based SQL data management tool",
"main": "index.js", "main": "index.js",
"bin": { "bin": {

View File

@ -1,95 +1,95 @@
/** /**
* @typedef {string} DSQL_DatabaseFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @typedef {string} DSQL_DatabaseFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
*/ */
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* @typedef {object} DSQL_DatabaseSchemaType * @typedef {object} DSQL_DatabaseSchemaType
* @property {string} dbName - Database Full name with spaces => "New Database" * @property {string} dbName - Database Full name with spaces => "New Database"
* @property {string} dbSlug - Database Slug => "new_database" * @property {string} dbSlug - Database Slug => "new_database"
* @property {string} dbFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @property {string} dbFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
* @property {string} [dbDescription] - Database brief description * @property {string} [dbDescription] - Database brief description
* @property {string} [dbImage] - Database image - Defaults to "/images/default.png" * @property {string} [dbImage] - Database image - Defaults to "/images/default.png"
* @property {DSQL_TableSchemaType[]} tables - List of database tables * @property {DSQL_TableSchemaType[]} tables - List of database tables
* @property {{ dbFullName: string }[]} [childrenDatabases] - List of children databases for current database which is parent * @property {{ dbFullName: string }[]} [childrenDatabases] - List of children databases for current database which is parent
* @property {boolean} [childDatabase] - If current database is a child of a different parent database * @property {boolean} [childDatabase] - If current database is a child of a different parent database
* @property {string} [childDatabaseDbFullName] - Parent database full name => "datasquirel_user_7_new_database" * @property {string} [childDatabaseDbFullName] - Parent database full name => "datasquirel_user_7_new_database"
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_TableSchemaType * @typedef {object} DSQL_TableSchemaType
* @property {string} tableName - Table slug (blog_posts) * @property {string} tableName - Table slug (blog_posts)
* @property {string} tableFullName - Table full name with spaces => "Blog Posts" * @property {string} tableFullName - Table full name with spaces => "Blog Posts"
* @property {string} [tableDescription] - Brief description of table * @property {string} [tableDescription] - Brief description of table
* @property {DSQL_FieldSchemaType[]} fields - List of table Fields * @property {DSQL_FieldSchemaType[]} fields - List of table Fields
* @property {DSQL_IndexSchemaType[]} [indexes] - List of table indexes, if available * @property {DSQL_IndexSchemaType[]} [indexes] - List of table indexes, if available
* @property {DSQL_ChildrenTablesType[]} [childrenTables] - List of children tables * @property {DSQL_ChildrenTablesType[]} [childrenTables] - List of children tables
* @property {boolean} [childTable] -If current table is a child clone * @property {boolean} [childTable] -If current table is a child clone
* @property {string} [childTableName] - Table slug of parent table => "blog_posts" * @property {string} [childTableName] - Table slug of parent table => "blog_posts"
* @property {string} [childTableDbFullName] - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @property {string} [childTableDbFullName] - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
* @property {string} [tableNameOld] - Old table name, incase of renaming table * @property {string} [tableNameOld] - Old table name, incase of renaming table
*/ */
/** /**
* @typedef {object} DSQL_ChildrenTablesType * @typedef {object} DSQL_ChildrenTablesType
* @property {string} dbNameFull - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @property {string} dbNameFull - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
* @property {string} tableName - Table slug => "blog_posts" * @property {string} tableName - Table slug => "blog_posts"
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_FieldSchemaType * @typedef {object} DSQL_FieldSchemaType
* @property {string} fieldName - Field Name(slug) => "long_description" * @property {string} fieldName - Field Name(slug) => "long_description"
* @property {string} [originName] - Field origin name(optional) * @property {string} [originName] - Field origin name(optional)
* @property {boolean} [updatedField] - Has this field been renamed? * @property {boolean} [updatedField] - Has this field been renamed?
* @property {string} dataType - Field Data type => "BIGIN" | "LONGTEXT" | "VARCHAR(***)" | ... * @property {string} dataType - Field Data type => "BIGIN" | "LONGTEXT" | "VARCHAR(***)" | ...
* @property {boolean} [nullValue] - Is this a null value or not? * @property {boolean} [nullValue] - Is this a null value or not?
* @property {boolean} [notNullValue] - Is this NOT a null value? * @property {boolean} [notNullValue] - Is this NOT a null value?
* @property {boolean} [primaryKey] - Is this the primary key for table? * @property {boolean} [primaryKey] - Is this the primary key for table?
* @property {boolean} [encrypted] - Is this field value encrypted? * @property {boolean} [encrypted] - Is this field value encrypted?
* @property {boolean} [autoIncrement] - Does this table primary key increment automatically? * @property {boolean} [autoIncrement] - Does this table primary key increment automatically?
* @property {string|number} [defaultValue] - Value of field by default * @property {string|number} [defaultValue] - Value of field by default
* @property {string} [defaultValueLiteral] - SQL key word which generates value automatically => "CURRENT_TIMESTAMP" * @property {string} [defaultValueLiteral] - SQL key word which generates value automatically => "CURRENT_TIMESTAMP"
* @property {DSQL_ForeignKeyType} [foreignKey] - Field foreign key reference object * @property {DSQL_ForeignKeyType} [foreignKey] - Field foreign key reference object
* @property {boolean} [richText] - Rich text field * @property {boolean} [richText] - Rich text field
* @property {string | RegExp} [pattern] - Field pattern for validation. Can be a string or a regular expression. Example: "^[a-zA-Z0-9_]*$" * @property {string | RegExp} [pattern] - Field pattern for validation. Can be a string or a regular expression. Example: "^[a-zA-Z0-9_]*$"
* @property {string} [patternFlags] - Field pattern flags for validation. Example: "i" * @property {string} [patternFlags] - Field pattern flags for validation. Example: "i"
*/ */
/** /**
* @typedef {object} DSQL_ForeignKeyType * @typedef {object} DSQL_ForeignKeyType
* @property {string} foreignKeyName - Unique Name of foreign key * @property {string} foreignKeyName - Unique Name of foreign key
* @property {string} destinationTableName - Reference table name(slug) => "blog_posts" * @property {string} destinationTableName - Reference table name(slug) => "blog_posts"
* @property {string} destinationTableColumnName - Reference column name(slug) => "id" * @property {string} destinationTableColumnName - Reference column name(slug) => "id"
* @property {string} destinationTableColumnType - Reference table field type => "BIGINT" | "VARCHAR(***)" | ... * @property {string} destinationTableColumnType - Reference table field type => "BIGINT" | "VARCHAR(***)" | ...
* @property {boolean} [cascadeDelete] - Does the reference table entry delete when this key is deleted? * @property {boolean} [cascadeDelete] - Does the reference table entry delete when this key is deleted?
* @property {boolean} [cascadeUpdate] - Does the reference table entry update when this key is updated? * @property {boolean} [cascadeUpdate] - Does the reference table entry update when this key is updated?
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_IndexSchemaType * @typedef {object} DSQL_IndexSchemaType
* @property {string} indexName - Unique Name of index => "blog_text_index" * @property {string} indexName - Unique Name of index => "blog_text_index"
* @property {string} indexType - "regular" or "fullText" * @property {string} indexType - "regular" or "fullText"
* @property {DSQL_IndexTableFieldType[]} indexTableFields - List of Index table fields * @property {DSQL_IndexTableFieldType[]} indexTableFields - List of Index table fields
* @property {string} [alias] - List of Index table fields * @property {string} [alias] - List of Index table fields
*/ */
/** /**
* @typedef {object} DSQL_IndexTableFieldType * @typedef {object} DSQL_IndexTableFieldType
* @property {string} value - Table Field Name * @property {string} value - Table Field Name
* @property {string} dataType - Table Field data type "VARCHAR(***)" | "BIGINT" | ... * @property {string} dataType - Table Field data type "VARCHAR(***)" | "BIGINT" | ...
*/ */
//////////////////////////////////////// ////////////////////////////////////////
exports.DSQL_TableSchemaType = DSQL_TableSchemaType; exports.DSQL_TableSchemaType = DSQL_TableSchemaType;

View File

@ -1,89 +1,89 @@
/** /**
* @typedef {string} DSQL_DatabaseFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @typedef {string} DSQL_DatabaseFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
*/ */
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* @typedef {object} DSQL_DatabaseSchemaType * @typedef {object} DSQL_DatabaseSchemaType
* @property {string} dbName - Database Full name with spaces => "New Database" * @property {string} dbName - Database Full name with spaces => "New Database"
* @property {string} dbSlug - Database Slug => "new_database" * @property {string} dbSlug - Database Slug => "new_database"
* @property {string} dbFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @property {string} dbFullName - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
* @property {string} [dbDescription] - Database brief description * @property {string} [dbDescription] - Database brief description
* @property {string} [dbImage] - Database image - Defaults to "/images/default.png" * @property {string} [dbImage] - Database image - Defaults to "/images/default.png"
* @property {DSQL_TableSchemaType[]} tables - List of database tables * @property {DSQL_TableSchemaType[]} tables - List of database tables
* @property {{ dbFullName: string }[]} [childrenDatabases] - List of children databases for current database which is parent * @property {{ dbFullName: string }[]} [childrenDatabases] - List of children databases for current database which is parent
* @property {boolean} [childDatabase] - If current database is a child of a different parent database * @property {boolean} [childDatabase] - If current database is a child of a different parent database
* @property {string} [childDatabaseDbFullName] - Parent database full name => "datasquirel_user_7_new_database" * @property {string} [childDatabaseDbFullName] - Parent database full name => "datasquirel_user_7_new_database"
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_TableSchemaType * @typedef {object} DSQL_TableSchemaType
* @property {string} tableName - Table slug (blog_posts) * @property {string} tableName - Table slug (blog_posts)
* @property {string} tableFullName - Table full name with spaces => "Blog Posts" * @property {string} tableFullName - Table full name with spaces => "Blog Posts"
* @property {string} [tableDescription] - Brief description of table * @property {string} [tableDescription] - Brief description of table
* @property {DSQL_FieldSchemaType[]} fields - List of table Fields * @property {DSQL_FieldSchemaType[]} fields - List of table Fields
* @property {DSQL_IndexSchemaType[]} [indexes] - List of table indexes, if available * @property {DSQL_IndexSchemaType[]} [indexes] - List of table indexes, if available
* @property {DSQL_ChildrenTablesType[]} childrenTables - List of children tables * @property {DSQL_ChildrenTablesType[]} childrenTables - List of children tables
* @property {boolean} [childTable] -If current table is a child clone * @property {boolean} [childTable] -If current table is a child clone
* @property {string} [childTableName] - Table slug of parent table => "blog_posts" * @property {string} [childTableName] - Table slug of parent table => "blog_posts"
* @property {string} [childTableDbFullName] - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @property {string} [childTableDbFullName] - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
* @property {string} [tableNameOld] - Old table name, incase of renaming table * @property {string} [tableNameOld] - Old table name, incase of renaming table
*/ */
/** /**
* @typedef {object} DSQL_ChildrenTablesType * @typedef {object} DSQL_ChildrenTablesType
* @property {string} dbNameFull - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database" * @property {string} dbNameFull - Database full name(slug) including datasquirel data => "datasquirel_user_7_new_database"
* @property {string} tableName - Table slug => "blog_posts" * @property {string} tableName - Table slug => "blog_posts"
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_FieldSchemaType * @typedef {object} DSQL_FieldSchemaType
* @property {string} fieldName - Field Name(slug) => "long_description" * @property {string} fieldName - Field Name(slug) => "long_description"
* @property {string} [originName] - Field origin name(optional) * @property {string} [originName] - Field origin name(optional)
* @property {boolean} [updatedField] - Has this field been renamed? * @property {boolean} [updatedField] - Has this field been renamed?
* @property {string} dataType - Field Data type => "BIGIN" | "LONGTEXT" | "VARCHAR(***)" | ... * @property {string} dataType - Field Data type => "BIGIN" | "LONGTEXT" | "VARCHAR(***)" | ...
* @property {boolean} [nullValue] - Is this a null value or not? * @property {boolean} [nullValue] - Is this a null value or not?
* @property {boolean} [notNullValue] - Is this NOT a null value? * @property {boolean} [notNullValue] - Is this NOT a null value?
* @property {boolean} [primaryKey] - Is this the primary key for table? * @property {boolean} [primaryKey] - Is this the primary key for table?
* @property {boolean} [encrypted] - Is this field value encrypted? * @property {boolean} [encrypted] - Is this field value encrypted?
* @property {boolean} [autoIncrement] - Does this table primary key increment automatically? * @property {boolean} [autoIncrement] - Does this table primary key increment automatically?
* @property {string|number} [defaultValue] - Value of field by default * @property {string|number} [defaultValue] - Value of field by default
* @property {string} [defaultValueLiteral] - SQL key word which generates value automatically => "CURRENT_TIMESTAMP" * @property {string} [defaultValueLiteral] - SQL key word which generates value automatically => "CURRENT_TIMESTAMP"
* @property {DSQL_ForeignKeyType} [foreignKey] - Field foreign key reference object * @property {DSQL_ForeignKeyType} [foreignKey] - Field foreign key reference object
*/ */
/** /**
* @typedef {object} DSQL_ForeignKeyType * @typedef {object} DSQL_ForeignKeyType
* @property {string} foreignKeyName - Unique Name of foreign key * @property {string} foreignKeyName - Unique Name of foreign key
* @property {string} destinationTableName - Reference table name(slug) => "blog_posts" * @property {string} destinationTableName - Reference table name(slug) => "blog_posts"
* @property {string} destinationTableColumnName - Reference column name(slug) => "id" * @property {string} destinationTableColumnName - Reference column name(slug) => "id"
* @property {string} destinationTableColumnType - Reference table field type => "BIGINT" | "VARCHAR(***)" | ... * @property {string} destinationTableColumnType - Reference table field type => "BIGINT" | "VARCHAR(***)" | ...
* @property {boolean} [cascadeDelete] - Does the reference table entry delete when this key is deleted? * @property {boolean} [cascadeDelete] - Does the reference table entry delete when this key is deleted?
* @property {boolean} [cascadeUpdate] - Does the reference table entry update when this key is updated? * @property {boolean} [cascadeUpdate] - Does the reference table entry update when this key is updated?
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_IndexSchemaType * @typedef {object} DSQL_IndexSchemaType
* @property {string} indexName - Unique Name of index => "blog_text_index" * @property {string} indexName - Unique Name of index => "blog_text_index"
* @property {string} indexType - "regular" or "fullText" * @property {string} indexType - "regular" or "fullText"
* @property {DSQL_IndexTableFieldType[]} indexTableFields - List of Index table fields * @property {DSQL_IndexTableFieldType[]} indexTableFields - List of Index table fields
*/ */
/** /**
* @typedef {object} DSQL_IndexTableFieldType * @typedef {object} DSQL_IndexTableFieldType
* @property {string} value - Table Field Name * @property {string} value - Table Field Name
* @property {string} dataType - Table Field data type "VARCHAR(***)" | "BIGINT" | ... * @property {string} dataType - Table Field data type "VARCHAR(***)" | "BIGINT" | ...
*/ */
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -1,11 +1,11 @@
const http = require("http"); const http = require("http");
/** /**
* @typedef {http.IncomingMessage} Request * @typedef {http.IncomingMessage} Request
*/ */
/** /**
* @typedef {http.ServerResponse} Response * @typedef {http.ServerResponse} Response
*/ */
module.exports = { Request, Response }; module.exports = { Request, Response };

View File

@ -1,48 +1,48 @@
/** /**
* @typedef {object} DSQL_MYSQL_SHOW_INDEXES_Type * @typedef {object} DSQL_MYSQL_SHOW_INDEXES_Type
* @property {string} Key_name - MYSQL Index Name * @property {string} Key_name - MYSQL Index Name
* @property {string} Table - Table Name(slug) * @property {string} Table - Table Name(slug)
* @property {string} Column_name * @property {string} Column_name
* @property {string} Collation * @property {string} Collation
* @property {string} Index_type - "FULL_TEXT" | ... * @property {string} Index_type - "FULL_TEXT" | ...
* @property {string} Cardinality * @property {string} Cardinality
* @property {string} Index_comment * @property {string} Index_comment
* @property {string} Comment * @property {string} Comment
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_MYSQL_SHOW_COLUMNS_Type * @typedef {object} DSQL_MYSQL_SHOW_COLUMNS_Type
* @property {string} Field - Field Name as represented in MSQL database * @property {string} Field - Field Name as represented in MSQL database
* @property {string} Type - varchar(***) | tinyint | bigint | ... * @property {string} Type - varchar(***) | tinyint | bigint | ...
* @property {string} Null * @property {string} Null
* @property {string} Key * @property {string} Key
* @property {string} Default * @property {string} Default
* @property {string} Extra * @property {string} Extra
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_MYSQL_FOREIGN_KEYS_Type * @typedef {object} DSQL_MYSQL_FOREIGN_KEYS_Type
* @property {string} CONSTRAINT_NAME - Constraint Name => "PRIMARY" | "MUL" | null | ... * @property {string} CONSTRAINT_NAME - Constraint Name => "PRIMARY" | "MUL" | null | ...
* @property {string} CONSTRAINT_SCHEMA - Database name * @property {string} CONSTRAINT_SCHEMA - Database name
* @property {string} TABLE_NAME - Table name * @property {string} TABLE_NAME - Table name
*/ */
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* @typedef {object} DSQL_MYSQL_user_databases_Type * @typedef {object} DSQL_MYSQL_user_databases_Type
* @property {number} user_id - User Id * @property {number} user_id - User Id
* @property {string} db_full_name - Database full name => eg. (dataasquirel_user_2_new_database) * @property {string} db_full_name - Database full name => eg. (dataasquirel_user_2_new_database)
* @property {string} db_name - Database name with spaces => eg. (New Database) * @property {string} db_name - Database name with spaces => eg. (New Database)
* @property {string} db_slug - Database slug => eg. (new_database) * @property {string} db_slug - Database slug => eg. (new_database)
* @property {string} db_image - Database image path * @property {string} db_image - Database image path
* @property {string} db_description - Database description * @property {string} db_description - Database description
* @property {number} active_clone - is Database active clone => 0 or 1 * @property {number} active_clone - is Database active clone => 0 or 1
* @property {string} active_clone_parent_db - Database parent db full name => eg. "datasquirel_user_7_wexculture" * @property {string} active_clone_parent_db - Database parent db full name => eg. "datasquirel_user_7_wexculture"
*/ */
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -1,15 +1,15 @@
/** /**
* @typedef {object} DATASQUIREL_LoggedInUser * @typedef {object} DATASQUIREL_LoggedInUser
* @property {number} id - user id (number) * @property {number} id - user id (number)
* @property {string} first_name - User First Name * @property {string} first_name - User First Name
* @property {string} last_name - User Last Name * @property {string} last_name - User Last Name
* @property {string} image - User Full Image * @property {string} image - User Full Image
* @property {string} image_thumbnail - User Image Thumbnail * @property {string} image_thumbnail - User Image Thumbnail
* @property {string} [social_id] - User Social id if available * @property {string} [social_id] - User Social id if available
* @property {number} social_login - 0 or 1 => is this user a social user(1) or not(0) * @property {number} social_login - 0 or 1 => is this user a social user(1) or not(0)
* @property {string} csrf_k - CSRF key * @property {string} csrf_k - CSRF key
* @property {boolean} logged_in_status - Is user logged in or not * @property {boolean} logged_in_status - Is user logged in or not
* @property {boolean} [date] - Time of session creation * @property {boolean} [date] - Time of session creation
*/ */
module.exports = { DATASQUIREL_LoggedInUser }; module.exports = { DATASQUIREL_LoggedInUser };

View File

@ -1,134 +1,134 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
const localAddUser = require("../engine/user/add-user"); const localAddUser = require("../engine/user/add-user");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} FunctionReturn * @typedef {object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {(Object[]|string)} [payload=[]] - Payload * @property {(Object[]|string)} [payload=[]] - Payload
*/ */
/** /**
* @typedef {object} UserDataPayload * @typedef {object} UserDataPayload
* @property {string} first_name - First Name *Required * @property {string} first_name - First Name *Required
* @property {string} last_name - Last Name *Required * @property {string} last_name - Last Name *Required
* @property {string} email - Email *Required * @property {string} email - Email *Required
* @property {string} password - Password *Required * @property {string} password - Password *Required
* @property {string?} username - Username (Optional) * @property {string?} username - Username (Optional)
*/ */
/** /**
* Add User to Database * Add User to Database
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {object} props - Single object passed * @param {object} props - Single object passed
* @param {string} props.key - FULL ACCESS API Key * @param {string} props.key - FULL ACCESS API Key
* @param {string} props.database - Database Name * @param {string} props.database - Database Name
* @param {UserDataPayload} props.payload - User Data Payload * @param {UserDataPayload} props.payload - User Data Payload
* *
* @returns { Promise<FunctionReturn> } * @returns { Promise<FunctionReturn> }
*/ */
async function addUser({ key, payload, database }) { async function addUser({ key, payload, database }) {
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
return await localAddUser({ return await localAddUser({
dbSchema: dbSchema, dbSchema: dbSchema,
payload: payload, payload: payload,
}); });
} }
} }
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
payload, payload,
database, database,
}); });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/add-user`, path: `/api/user/add-user`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = addUser; module.exports = addUser;

View File

@ -1,106 +1,106 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const decrypt = require("../functions/decrypt"); const decrypt = require("../functions/decrypt");
const parseCookies = require("../utils/functions/parseCookies"); const parseCookies = require("../utils/functions/parseCookies");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* Get just the access token for user * Get just the access token for user
* ============================================================================== * ==============================================================================
* @description This Function takes in a request object and returns a user token * @description This Function takes in a request object and returns a user token
* string and csrf token string * string and csrf token string
* *
* @param {Object} params - Arg * @param {Object} params - Arg
* @param {http.IncomingMessage} params.request - Http request object * @param {http.IncomingMessage} params.request - Http request object
* @param {string} params.encryptionKey - Encryption Key * @param {string} params.encryptionKey - Encryption Key
* @param {string} params.encryptionSalt - Encryption Salt * @param {string} params.encryptionSalt - Encryption Salt
* @param {string} params.database - Database Name * @param {string} params.database - Database Name
* *
* @returns {{ key: string | undefined, csrf: string | undefined }} * @returns {{ key: string | undefined, csrf: string | undefined }}
*/ */
function getToken({ request, encryptionKey, encryptionSalt, database }) { function getToken({ request, encryptionKey, encryptionSalt, database }) {
try { try {
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
const cookies = parseCookies({ request }); const cookies = parseCookies({ request });
const dsqluid = cookies.dsqluid; const dsqluid = cookies.dsqluid;
const authKeyName = `datasquirel_${dsqluid}_${database}_auth_key`; const authKeyName = `datasquirel_${dsqluid}_${database}_auth_key`;
const csrfName = `datasquirel_${dsqluid}_${database}_csrf`; const csrfName = `datasquirel_${dsqluid}_${database}_csrf`;
const key = cookies[authKeyName]; const key = cookies[authKeyName];
const csrf = cookies[csrfName]; const csrf = cookies[csrfName];
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
let userPayload = decrypt({ let userPayload = decrypt({
encryptedString: key, encryptedString: key,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
if (!userPayload) { if (!userPayload) {
return { key: undefined, csrf: undefined }; return { key: undefined, csrf: undefined };
} }
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
let userObject = JSON.parse(userPayload); let userObject = JSON.parse(userPayload);
if (!userObject.csrf_k) { if (!userObject.csrf_k) {
return { key: undefined, csrf: undefined }; return { key: undefined, csrf: undefined };
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** /**
* Return User Object * Return User Object
* *
* @description Return User Object * @description Return User Object
*/ */
return { key, csrf }; return { key, csrf };
} catch (error) { } catch (error) {
/** /**
* Return User Object * Return User Object
* *
* @description Return User Object * @description Return User Object
*/ */
return { return {
key: undefined, key: undefined,
csrf: undefined, csrf: undefined,
}; };
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = getToken; module.exports = getToken;

View File

@ -1,144 +1,144 @@
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
const getLocalUser = require("../engine/user/get-user"); const getLocalUser = require("../engine/user/get-user");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} FunctionReturn * @typedef {object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {{ * @property {{
* id: number, * id: number,
* first_name: string, * first_name: string,
* last_name: string, * last_name: string,
* username: string, * username: string,
* email: string, * email: string,
* phone: string, * phone: string,
* social_id: [string], * social_id: [string],
* image: string, * image: string,
* image_thumbnail: string, * image_thumbnail: string,
* verification_status: [number=0], * verification_status: [number=0],
* }} payload - Payload * }} payload - Payload
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {object} params - Single Param object containing params * @param {object} params - Single Param object containing params
* @param {String} params.key - API Key * @param {String} params.key - API Key
* @param {String} params.database - Target Database * @param {String} params.database - Target Database
* @param {number} params.userId - user id * @param {number} params.userId - user id
* @param {string[]} [params.fields] - fields to select * @param {string[]} [params.fields] - fields to select
* *
* @returns { Promise<FunctionReturn>} * @returns { Promise<FunctionReturn>}
*/ */
async function getUser({ key, userId, database, fields }) { async function getUser({ key, userId, database, fields }) {
/** /**
* Initialize * Initialize
*/ */
const defaultFields = ["id", "first_name", "last_name", "email", "username", "image", "image_thumbnail", "verification_status", "date_created", "date_created_code", "date_created_timestamp", "date_updated", "date_updated_code", "date_updated_timestamp"]; const defaultFields = ["id", "first_name", "last_name", "email", "username", "image", "image_thumbnail", "verification_status", "date_created", "date_created_code", "date_created_timestamp", "date_updated", "date_updated_code", "date_updated_timestamp"];
const updatedFields = fields && fields[0] ? [...defaultFields, ...fields] : defaultFields; const updatedFields = fields && fields[0] ? [...defaultFields, ...fields] : defaultFields;
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
userId, userId,
database, database,
fields: [...new Set(updatedFields)], fields: [...new Set(updatedFields)],
}); });
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
return await getLocalUser({ return await getLocalUser({
userId, userId,
fields: [...new Set(updatedFields)], fields: [...new Set(updatedFields)],
dbSchema, dbSchema,
}); });
} }
} }
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/get-user`, path: `/api/user/get-user`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = getUser; module.exports = getUser;

View File

@ -1,204 +1,204 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const encrypt = require("../functions/encrypt"); const encrypt = require("../functions/encrypt");
const loginLocalUser = require("../engine/user/login-user"); const loginLocalUser = require("../engine/user/login-user");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} AuthenticatedUser * @typedef {object} AuthenticatedUser
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {import("../types/user.td").DATASQUIREL_LoggedInUser | null} payload - Payload of the response * @property {import("../types/user.td").DATASQUIREL_LoggedInUser | null} payload - Payload of the response
* @property {string} [msg] - An optional message * @property {string} [msg] - An optional message
* @property {number} [userId] - An optional message * @property {number} [userId] - An optional message
*/ */
/** /**
* Login A user * Login A user
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {object} params - Single Param object containing params * @param {object} params - Single Param object containing params
* @param {String} params.key - FULL ACCESS API Key * @param {String} params.key - FULL ACCESS API Key
* @param {String} params.database - Target Database * @param {String} params.database - Target Database
* @param {{ * @param {{
* email?: string, * email?: string,
* username?: string, * username?: string,
* password: string, * password: string,
* }} params.payload Login Email/Username and Password * }} params.payload Login Email/Username and Password
* @param {string[]} [params.additionalFields] - Additional Fields to be added to the user object * @param {string[]} [params.additionalFields] - Additional Fields to be added to the user object
* @param {http.ServerResponse} params.response - Http response object * @param {http.ServerResponse} params.response - Http response object
* @param {String} params.encryptionKey - Encryption Key * @param {String} params.encryptionKey - Encryption Key
* @param {String} params.encryptionSalt - Encryption Salt * @param {String} params.encryptionSalt - Encryption Salt
* *
* @returns { Promise<AuthenticatedUser>} * @returns { Promise<AuthenticatedUser>}
*/ */
async function loginUser({ key, payload, database, additionalFields, response, encryptionKey, encryptionSalt }) { async function loginUser({ key, payload, database, additionalFields, response, encryptionKey, encryptionSalt }) {
/** /**
* Check Encryption Keys * Check Encryption Keys
* *
* @description Check Encryption Keys * @description Check Encryption Keys
*/ */
if (!encryptionKey?.match(/./)) if (!encryptionKey?.match(/./))
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Encryption Key Required", msg: "Encryption Key Required",
}; };
if (!encryptionSalt?.match(/./)) if (!encryptionSalt?.match(/./))
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Encryption Salt Required", msg: "Encryption Salt Required",
}; };
if (encryptionKey.length < 24) if (encryptionKey.length < 24)
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Encryption Key must be at least 24 characters", msg: "Encryption Key must be at least 24 characters",
}; };
if (encryptionSalt.length < 8) if (encryptionSalt.length < 8)
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Encryption Salt must be at least 8 characters", msg: "Encryption Salt must be at least 8 characters",
}; };
/** /**
* Initialize HTTP response variable * Initialize HTTP response variable
*/ */
let httpResponse; let httpResponse;
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
httpResponse = await loginLocalUser({ httpResponse = await loginLocalUser({
payload, payload,
additionalFields, additionalFields,
dbSchema, dbSchema,
}); });
} }
} else { } else {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
* *
* @type {{ success: boolean, payload: import("../types/user.td").DATASQUIREL_LoggedInUser | null, userId?: number, msg?: string }} * @type {{ success: boolean, payload: import("../types/user.td").DATASQUIREL_LoggedInUser | null, userId?: number, msg?: string }}
*/ */
httpResponse = await new Promise((resolve, reject) => { httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
payload, payload,
database, database,
additionalFields, additionalFields,
}); });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/login-user`, path: `/api/user/login-user`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
if (httpResponse?.success) { if (httpResponse?.success) {
let encryptedPayload = encrypt({ let encryptedPayload = encrypt({
data: JSON.stringify(httpResponse.payload), data: JSON.stringify(httpResponse.payload),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
const { userId } = httpResponse; const { userId } = httpResponse;
const authKeyName = `datasquirel_${userId}_${database}_auth_key`; const authKeyName = `datasquirel_${userId}_${database}_auth_key`;
const csrfName = `datasquirel_${userId}_${database}_csrf`; const csrfName = `datasquirel_${userId}_${database}_csrf`;
response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${httpResponse.payload?.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${userId};samesite=strict;path=/;HttpOnly=true`]); response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${httpResponse.payload?.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${userId};samesite=strict;path=/;HttpOnly=true`]);
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = loginUser; module.exports = loginUser;

View File

@ -1,74 +1,74 @@
// @ts-check // @ts-check
const http = require("http"); const http = require("http");
const parseCookies = require("../utils/functions/parseCookies"); const parseCookies = require("../utils/functions/parseCookies");
/** /**
* Logout user * Logout user
* ============================================================================== * ==============================================================================
* @param {object} params - Single Param object containing params * @param {object} params - Single Param object containing params
* @param {http.IncomingMessage} params.request - Http request object * @param {http.IncomingMessage} params.request - Http request object
* @param {http.ServerResponse} params.response - Http response object * @param {http.ServerResponse} params.response - Http response object
* @param {string} [params.database] - Target database name(slug): optional => If you don't * @param {string} [params.database] - Target database name(slug): optional => If you don't
* include this you will be logged out of all datasquirel websites instead of just the target * include this you will be logged out of all datasquirel websites instead of just the target
* database * database
* *
* @returns {{success: boolean, payload: string}} * @returns {{success: boolean, payload: string}}
*/ */
function logoutUser({ request, response, database }) { function logoutUser({ request, response, database }) {
/** /**
* Check Encryption Keys * Check Encryption Keys
* *
* @description Check Encryption Keys * @description Check Encryption Keys
*/ */
try { try {
const cookies = parseCookies({ request }); const cookies = parseCookies({ request });
const cookiesKeys = Object.keys(cookies); const cookiesKeys = Object.keys(cookies);
const dbUid = cookies.dsqluid; const dbUid = cookies.dsqluid;
const keyRegexp = new RegExp(`datasquirel_${dbUid}_${database}_auth_key`); const keyRegexp = new RegExp(`datasquirel_${dbUid}_${database}_auth_key`);
const csrfRegexp = new RegExp(`datasquirel_${dbUid}_${database}_csrf`); const csrfRegexp = new RegExp(`datasquirel_${dbUid}_${database}_csrf`);
const authKeyName = cookiesKeys.filter((cookieKey) => cookieKey.match(keyRegexp))[0]; const authKeyName = cookiesKeys.filter((cookieKey) => cookieKey.match(keyRegexp))[0];
const csrfName = cookiesKeys.filter((cookieKey) => cookieKey.match(csrfRegexp))[0]; const csrfName = cookiesKeys.filter((cookieKey) => cookieKey.match(csrfRegexp))[0];
if (authKeyName && csrfName) { if (authKeyName && csrfName) {
response.setHeader("Set-Cookie", [`${authKeyName}=null;samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=null;samesite=strict;path=/;HttpOnly=true`, `dsqluid=null;samesite=strict;path=/;HttpOnly=true`]); response.setHeader("Set-Cookie", [`${authKeyName}=null;samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=null;samesite=strict;path=/;HttpOnly=true`, `dsqluid=null;samesite=strict;path=/;HttpOnly=true`]);
} else { } else {
const allKeys = cookiesKeys.filter((cookieKey) => cookieKey.match(/datasquirel_.*_auth_key/)); const allKeys = cookiesKeys.filter((cookieKey) => cookieKey.match(/datasquirel_.*_auth_key/));
const allCsrfs = cookiesKeys.filter((cookieKey) => cookieKey.match(/datasquirel_.*_csrf/)); const allCsrfs = cookiesKeys.filter((cookieKey) => cookieKey.match(/datasquirel_.*_csrf/));
response.setHeader("Set-Cookie", [...allKeys.map((key) => `${key}=null;samesite=strict;path=/;HttpOnly=true;Secure=true`), ...allCsrfs.map((csrf) => `${csrf}=null;samesite=strict;path=/;HttpOnly=true`), `dsqluid=null;samesite=strict;path=/;HttpOnly=true`]); response.setHeader("Set-Cookie", [...allKeys.map((key) => `${key}=null;samesite=strict;path=/;HttpOnly=true;Secure=true`), ...allCsrfs.map((csrf) => `${csrf}=null;samesite=strict;path=/;HttpOnly=true`), `dsqluid=null;samesite=strict;path=/;HttpOnly=true`]);
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return { return {
success: true, success: true,
payload: "User Logged Out", payload: "User Logged Out",
}; };
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
} catch (error) { } catch (error) {
console.log(error); console.log(error);
return { return {
success: false, success: false,
payload: "Logout Failed", payload: "Logout Failed",
}; };
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = logoutUser; module.exports = logoutUser;

View File

@ -1,190 +1,190 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const encrypt = require("../functions/encrypt"); const encrypt = require("../functions/encrypt");
const userAuth = require("./user-auth"); const userAuth = require("./user-auth");
const localReauthUser = require("../engine/user/reauth-user"); const localReauthUser = require("../engine/user/reauth-user");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} FunctionReturn * @typedef {object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {import("../types/user.td").DATASQUIREL_LoggedInUser | null} payload - Payload * @property {import("../types/user.td").DATASQUIREL_LoggedInUser | null} payload - Payload
* @property {string} [msg] - Response Message * @property {string} [msg] - Response Message
* @property {number} [userId] - user ID * @property {number} [userId] - user ID
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {object} params - Single Param object containing params * @param {object} params - Single Param object containing params
* @param {String} params.key - API Key * @param {String} params.key - API Key
* @param {String} params.database - Target Database * @param {String} params.database - Target Database
* @param {http.ServerResponse} params.response - Http response object * @param {http.ServerResponse} params.response - Http response object
* @param {http.IncomingMessage} params.request - Http request object * @param {http.IncomingMessage} params.request - Http request object
* @param {("deep" | "normal")} [params.level] - Authentication level * @param {("deep" | "normal")} [params.level] - Authentication level
* @param {String} params.encryptionKey - Encryption Key * @param {String} params.encryptionKey - Encryption Key
* @param {String} params.encryptionSalt - Encryption Salt * @param {String} params.encryptionSalt - Encryption Salt
* @param {string[]} [params.additionalFields] - Additional Fields to be added to the user object * @param {string[]} [params.additionalFields] - Additional Fields to be added to the user object
* *
* @returns { Promise<FunctionReturn> } * @returns { Promise<FunctionReturn> }
*/ */
async function reauthUser({ key, database, response, request, level, encryptionKey, encryptionSalt, additionalFields }) { async function reauthUser({ key, database, response, request, level, encryptionKey, encryptionSalt, additionalFields }) {
/** /**
* Check Encryption Keys * Check Encryption Keys
* *
* @description Check Encryption Keys * @description Check Encryption Keys
*/ */
const existingUser = userAuth({ const existingUser = userAuth({
database, database,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
level, level,
request, request,
}); });
if (!existingUser?.payload?.id) { if (!existingUser?.payload?.id) {
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Cookie Credentials Invalid", msg: "Cookie Credentials Invalid",
}; };
} }
/** /**
* Initialize HTTP response variable * Initialize HTTP response variable
*/ */
let httpResponse; let httpResponse;
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
httpResponse = await localReauthUser({ httpResponse = await localReauthUser({
existingUser: existingUser.payload, existingUser: existingUser.payload,
additionalFields, additionalFields,
dbSchema, dbSchema,
}); });
} }
} else { } else {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
httpResponse = await new Promise((resolve, reject) => { httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
existingUser: existingUser.payload, existingUser: existingUser.payload,
database, database,
additionalFields, additionalFields,
}); });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/reauth-user`, path: `/api/user/reauth-user`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
if (httpResponse?.success) { if (httpResponse?.success) {
let encryptedPayload = encrypt({ let encryptedPayload = encrypt({
data: JSON.stringify(httpResponse.payload), data: JSON.stringify(httpResponse.payload),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
const { userId } = httpResponse; const { userId } = httpResponse;
const authKeyName = `datasquirel_${userId}_${database}_auth_key`; const authKeyName = `datasquirel_${userId}_${database}_auth_key`;
const csrfName = `datasquirel_${userId}_${database}_csrf`; const csrfName = `datasquirel_${userId}_${database}_csrf`;
response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${httpResponse.payload.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${userId};samesite=strict;path=/;HttpOnly=true`]); response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${httpResponse.payload.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${userId};samesite=strict;path=/;HttpOnly=true`]);
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = reauthUser; module.exports = reauthUser;

View File

@ -1,251 +1,251 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const encrypt = require("../../functions/encrypt"); const encrypt = require("../../functions/encrypt");
const localGithubAuth = require("../../engine/user/social/github-auth"); const localGithubAuth = require("../../engine/user/social/github-auth");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} FunctionReturn * @typedef {object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {{id: number, first_name: string, last_name: string, csrf_k: string, social_id: string} | null} user - Returned User * @property {{id: number, first_name: string, last_name: string, csrf_k: string, social_id: string} | null} user - Returned User
* @property {number} [dsqlUserId] - Dsql User Id * @property {number} [dsqlUserId] - Dsql User Id
* @property {string} [msg] - Response message * @property {string} [msg] - Response message
*/ */
/** /**
* SERVER FUNCTION: Login with google Function * SERVER FUNCTION: Login with google Function
* ============================================================================== * ==============================================================================
* *
* @async * @async
* *
* @param {object} params - main params object * @param {object} params - main params object
* @param {string} params.key - API full access key * @param {string} params.key - API full access key
* @param {string} params.code - Github access code gotten from the client side * @param {string} params.code - Github access code gotten from the client side
* @param {string?} params.email - Email gotten from the client side if available * @param {string?} params.email - Email gotten from the client side if available
* @param {string} params.database - Target database name(slug) * @param {string} params.database - Target database name(slug)
* @param {string} params.clientId - Github client id * @param {string} params.clientId - Github client id
* @param {string} params.clientSecret - Github client Secret * @param {string} params.clientSecret - Github client Secret
* @param {http.ServerResponse} params.response - HTTPS response object * @param {http.ServerResponse} params.response - HTTPS response object
* @param {string} params.encryptionKey - Encryption key * @param {string} params.encryptionKey - Encryption key
* @param {string} params.encryptionSalt - Encryption salt * @param {string} params.encryptionSalt - Encryption salt
* @param {object} [params.additionalFields] - Additional Fields to be added to the user object * @param {object} [params.additionalFields] - Additional Fields to be added to the user object
* *
* @returns { Promise<FunctionReturn | undefined> } * @returns { Promise<FunctionReturn | undefined> }
*/ */
async function githubAuth({ key, code, email, database, clientId, clientSecret, response, encryptionKey, encryptionSalt, additionalFields }) { async function githubAuth({ key, code, email, database, clientId, clientSecret, response, encryptionKey, encryptionSalt, additionalFields }) {
/** /**
* Check inputs * Check inputs
* *
* @description Check inputs * @description Check inputs
*/ */
if (!key || key?.match(/ /)) { if (!key || key?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please enter API full access Key", msg: "Please enter API full access Key",
}; };
} }
if (!code || code?.match(/ /)) { if (!code || code?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please enter Github Access Token", msg: "Please enter Github Access Token",
}; };
} }
if (!database || database?.match(/ /)) { if (!database || database?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide database slug name you want to access", msg: "Please provide database slug name you want to access",
}; };
} }
if (!clientId || clientId?.match(/ /)) { if (!clientId || clientId?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please enter Github OAUTH client ID", msg: "Please enter Github OAUTH client ID",
}; };
} }
if (!response || !response?.setHeader) { if (!response || !response?.setHeader) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide a valid HTTPS response object", msg: "Please provide a valid HTTPS response object",
}; };
} }
if (!encryptionKey || encryptionKey?.match(/ /)) { if (!encryptionKey || encryptionKey?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide a valid encryption key", msg: "Please provide a valid encryption key",
}; };
} }
if (!encryptionSalt || encryptionSalt?.match(/ /)) { if (!encryptionSalt || encryptionSalt?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide a valid encryption salt", msg: "Please provide a valid encryption salt",
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Initialize HTTP response variable * Initialize HTTP response variable
*/ */
let httpResponse; let httpResponse;
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
httpResponse = await localGithubAuth({ httpResponse = await localGithubAuth({
dbSchema: dbSchema, dbSchema: dbSchema,
code, code,
email: email || undefined, email: email || undefined,
clientId, clientId,
clientSecret, clientSecret,
additionalFields, additionalFields,
res: response, res: response,
}); });
} }
} else { } else {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
* @type {FunctionReturn} - Https response object * @type {FunctionReturn} - Https response object
*/ */
httpResponse = await new Promise((resolve, reject) => { httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
code, code,
email, email,
clientId, clientId,
clientSecret, clientSecret,
database, database,
additionalFields, additionalFields,
}); });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/github-login`, path: `/api/user/github-login`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
try { try {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
resolve({ resolve({
success: false, success: false,
user: null, user: null,
msg: "Something went wrong", msg: "Something went wrong",
}); });
} }
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
if (httpResponse?.success && httpResponse?.user) { if (httpResponse?.success && httpResponse?.user) {
let encryptedPayload = encrypt({ let encryptedPayload = encrypt({
data: JSON.stringify(httpResponse.user), data: JSON.stringify(httpResponse.user),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
const { user, dsqlUserId } = httpResponse; const { user, dsqlUserId } = httpResponse;
const authKeyName = `datasquirel_${dsqlUserId}_${database}_auth_key`; const authKeyName = `datasquirel_${dsqlUserId}_${database}_auth_key`;
const csrfName = `datasquirel_${dsqlUserId}_${database}_csrf`; const csrfName = `datasquirel_${dsqlUserId}_${database}_csrf`;
response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${user.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${dsqlUserId};samesite=strict;path=/;HttpOnly=true`, `datasquirel_social_id=${user.social_id};samesite=strict;path=/`]); response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${user.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${dsqlUserId};samesite=strict;path=/;HttpOnly=true`, `datasquirel_social_id=${user.social_id};samesite=strict;path=/`]);
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return httpResponse; return httpResponse;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = githubAuth; module.exports = githubAuth;

View File

@ -1,239 +1,239 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const https = require("https"); const https = require("https");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const encrypt = require("../../functions/encrypt"); const encrypt = require("../../functions/encrypt");
const localGoogleAuth = require("../../engine/user/social/google-auth"); const localGoogleAuth = require("../../engine/user/social/google-auth");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object | null} FunctionReturn * @typedef {object | null} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {import("../../types/user.td").DATASQUIREL_LoggedInUser | null} user - Returned User * @property {import("../../types/user.td").DATASQUIREL_LoggedInUser | null} user - Returned User
* @property {number} [dsqlUserId] - Dsql User Id * @property {number} [dsqlUserId] - Dsql User Id
* @property {string} [msg] - Response message * @property {string} [msg] - Response message
*/ */
/** /**
* SERVER FUNCTION: Login with google Function * SERVER FUNCTION: Login with google Function
* ============================================================================== * ==============================================================================
* *
* @async * @async
* *
* @param {object} params - main params object * @param {object} params - main params object
* @param {string} params.key - API full access key * @param {string} params.key - API full access key
* @param {string} params.token - Google access token gotten from the client side * @param {string} params.token - Google access token gotten from the client side
* @param {string} params.database - Target database name(slug) * @param {string} params.database - Target database name(slug)
* @param {string} params.clientId - Google client id * @param {string} params.clientId - Google client id
* @param {http.ServerResponse} params.response - HTTPS response object * @param {http.ServerResponse} params.response - HTTPS response object
* @param {string} params.encryptionKey - Encryption key * @param {string} params.encryptionKey - Encryption key
* @param {string} params.encryptionSalt - Encryption salt * @param {string} params.encryptionSalt - Encryption salt
* @param {object} [params.additionalFields] - Additional Fields to be added to the user object * @param {object} [params.additionalFields] - Additional Fields to be added to the user object
* *
* @returns { Promise<FunctionReturn> } * @returns { Promise<FunctionReturn> }
*/ */
async function googleAuth({ key, token, database, clientId, response, encryptionKey, encryptionSalt, additionalFields }) { async function googleAuth({ key, token, database, clientId, response, encryptionKey, encryptionSalt, additionalFields }) {
/** /**
* Check inputs * Check inputs
* *
* @description Check inputs * @description Check inputs
*/ */
if (!key || key?.match(/ /)) { if (!key || key?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please enter API full access Key", msg: "Please enter API full access Key",
}; };
} }
if (!token || token?.match(/ /)) { if (!token || token?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please enter Google Access Token", msg: "Please enter Google Access Token",
}; };
} }
if (!database || database?.match(/ /)) { if (!database || database?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide database slug name you want to access", msg: "Please provide database slug name you want to access",
}; };
} }
if (!clientId || clientId?.match(/ /)) { if (!clientId || clientId?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please enter Google OAUTH client ID", msg: "Please enter Google OAUTH client ID",
}; };
} }
if (!response || !response?.setHeader) { if (!response || !response?.setHeader) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide a valid HTTPS response object", msg: "Please provide a valid HTTPS response object",
}; };
} }
if (!encryptionKey || encryptionKey?.match(/ /)) { if (!encryptionKey || encryptionKey?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide a valid encryption key", msg: "Please provide a valid encryption key",
}; };
} }
if (!encryptionSalt || encryptionSalt?.match(/ /)) { if (!encryptionSalt || encryptionSalt?.match(/ /)) {
return { return {
success: false, success: false,
user: null, user: null,
msg: "Please provide a valid encryption salt", msg: "Please provide a valid encryption salt",
}; };
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Initialize HTTP response variable * Initialize HTTP response variable
*/ */
let httpResponse; let httpResponse;
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
httpResponse = await localGoogleAuth({ httpResponse = await localGoogleAuth({
dbSchema: dbSchema, dbSchema: dbSchema,
token, token,
clientId, clientId,
additionalFields, additionalFields,
response: response, response: response,
}); });
} }
} else { } else {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
* @type {{ success: boolean, user: import("../../types/user.td").DATASQUIREL_LoggedInUser | null, msg?: string, dsqlUserId?: number } | null } - Https response object * @type {{ success: boolean, user: import("../../types/user.td").DATASQUIREL_LoggedInUser | null, msg?: string, dsqlUserId?: number } | null } - Https response object
*/ */
httpResponse = await new Promise((resolve, reject) => { httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
token, token,
clientId, clientId,
database, database,
additionalFields, additionalFields,
}); });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/google-login`, path: `/api/user/google-login`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
if (httpResponse?.success && httpResponse?.user) { if (httpResponse?.success && httpResponse?.user) {
let encryptedPayload = encrypt({ let encryptedPayload = encrypt({
data: JSON.stringify(httpResponse.user), data: JSON.stringify(httpResponse.user),
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
const { user, dsqlUserId } = httpResponse; const { user, dsqlUserId } = httpResponse;
const authKeyName = `datasquirel_${dsqlUserId}_${database}_auth_key`; const authKeyName = `datasquirel_${dsqlUserId}_${database}_auth_key`;
const csrfName = `datasquirel_${dsqlUserId}_${database}_csrf`; const csrfName = `datasquirel_${dsqlUserId}_${database}_csrf`;
response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${user.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${dsqlUserId};samesite=strict;path=/;HttpOnly=true`, `datasquirel_social_id=${user.social_id};samesite=strict;path=/`]); response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${user.csrf_k};samesite=strict;path=/;HttpOnly=true`, `dsqluid=${dsqlUserId};samesite=strict;path=/;HttpOnly=true`, `datasquirel_social_id=${user.social_id};samesite=strict;path=/`]);
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return httpResponse; return httpResponse;
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
module.exports = googleAuth; module.exports = googleAuth;

View File

@ -1,126 +1,126 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
const localUpdateUser = require("../engine/user/update-user"); const localUpdateUser = require("../engine/user/update-user");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} FunctionReturn * @typedef {object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {(Object[]|string)} [payload=[]] - Payload * @property {(Object[]|string)} [payload=[]] - Payload
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {object} params - API Key * @param {object} params - API Key
* @param {String} params.key - API Key * @param {String} params.key - API Key
* @param {String} params.database - Target Database * @param {String} params.database - Target Database
* @param {{ id: number }} params.payload - User Object * @param {{ id: number }} params.payload - User Object
* *
* @returns { Promise<FunctionReturn>} * @returns { Promise<FunctionReturn>}
*/ */
async function updateUser({ key, payload, database }) { async function updateUser({ key, payload, database }) {
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
if (dbSchema) { if (dbSchema) {
return await localUpdateUser({ return await localUpdateUser({
dbSchema: dbSchema, dbSchema: dbSchema,
payload: payload, payload: payload,
}); });
} }
} }
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ const reqPayload = JSON.stringify({
payload, payload,
database, database,
}); });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/user/update-user`, path: `/api/user/update-user`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = updateUser; module.exports = updateUser;

View File

@ -1,143 +1,143 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const decrypt = require("../functions/decrypt"); const decrypt = require("../functions/decrypt");
const parseCookies = require("../utils/functions/parseCookies"); const parseCookies = require("../utils/functions/parseCookies");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {object} AuthenticatedUserObject * @typedef {object} AuthenticatedUserObject
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {import("../types/user.td").DATASQUIREL_LoggedInUser | null} payload - Payload * @property {import("../types/user.td").DATASQUIREL_LoggedInUser | null} payload - Payload
* @property {string | unknown} [msg] - Response Message * @property {string | unknown} [msg] - Response Message
*/ */
/** /**
* Authenticate User from request * Authenticate User from request
* ============================================================================== * ==============================================================================
* @description This Function takes in a request object and returns a user object * @description This Function takes in a request object and returns a user object
* with the user's data * with the user's data
* *
* @param {Object} params - Arg * @param {Object} params - Arg
* @param {http.IncomingMessage} params.request - Http request object * @param {http.IncomingMessage} params.request - Http request object
* @param {string} params.encryptionKey - Encryption Key * @param {string} params.encryptionKey - Encryption Key
* @param {string} params.encryptionSalt - Encryption Salt * @param {string} params.encryptionSalt - Encryption Salt
* @param {("deep" | "normal")} [params.level] - Optional. "Deep" value indicates an extra layer of security * @param {("deep" | "normal")} [params.level] - Optional. "Deep" value indicates an extra layer of security
* @param {string} params.database - Database Name * @param {string} params.database - Database Name
* *
* @returns { AuthenticatedUserObject } * @returns { AuthenticatedUserObject }
*/ */
function userAuth({ request, encryptionKey, encryptionSalt, level, database }) { function userAuth({ request, encryptionKey, encryptionSalt, level, database }) {
try { try {
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
const cookies = parseCookies({ request }); const cookies = parseCookies({ request });
const dsqluid = cookies.dsqluid; const dsqluid = cookies.dsqluid;
const authKeyName = `datasquirel_${dsqluid}_${database}_auth_key`; const authKeyName = `datasquirel_${dsqluid}_${database}_auth_key`;
const csrfName = `datasquirel_${dsqluid}_${database}_csrf`; const csrfName = `datasquirel_${dsqluid}_${database}_csrf`;
const key = cookies[authKeyName]; const key = cookies[authKeyName];
const csrf = cookies[csrfName]; const csrf = cookies[csrfName];
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
let userPayload = decrypt({ let userPayload = decrypt({
encryptedString: key, encryptedString: key,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
if (!userPayload) { if (!userPayload) {
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "Couldn't Decrypt cookie", msg: "Couldn't Decrypt cookie",
}; };
} }
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
let userObject = JSON.parse(userPayload); let userObject = JSON.parse(userPayload);
if (!userObject.csrf_k) { if (!userObject.csrf_k) {
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "No CSRF_K in decrypted payload", msg: "No CSRF_K in decrypted payload",
}; };
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
if (level?.match(/deep/i) && !csrf?.match(new RegExp(`${userObject.csrf_k}`))) { if (level?.match(/deep/i) && !csrf?.match(new RegExp(`${userObject.csrf_k}`))) {
return { return {
success: false, success: false,
payload: null, payload: null,
msg: "CSRF_K requested but does not match payload", msg: "CSRF_K requested but does not match payload",
}; };
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** /**
* Return User Object * Return User Object
* *
* @description Return User Object * @description Return User Object
*/ */
return { return {
success: true, success: true,
payload: userObject, payload: userObject,
}; };
} catch (error) { } catch (error) {
/** /**
* Return User Object * Return User Object
* *
* @description Return User Object * @description Return User Object
*/ */
return { return {
success: false, success: false,
payload: null, payload: null,
msg: error, msg: error,
}; };
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = userAuth; module.exports = userAuth;

View File

@ -1,96 +1,96 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
const decrypt = require("../functions/decrypt"); const decrypt = require("../functions/decrypt");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* Validate Token * Validate Token
* ============================================================================== * ==============================================================================
* @description This Function takes in a encrypted token and returns a user object * @description This Function takes in a encrypted token and returns a user object
* *
* @param {Object} params - Arg * @param {Object} params - Arg
* @param {string} params.token - Encrypted Token * @param {string} params.token - Encrypted Token
* @param {string} params.encryptionKey - Encryption Key * @param {string} params.encryptionKey - Encryption Key
* @param {string} params.encryptionSalt - Encryption Salt * @param {string} params.encryptionSalt - Encryption Salt
* @param {("deep" | "normal")?} [params.level] - Optional. "Deep" value indicates an extra layer of security * @param {("deep" | "normal")?} [params.level] - Optional. "Deep" value indicates an extra layer of security
* @param {string} params.database - Database Name * @param {string} params.database - Database Name
* *
* @returns { import("../types/user.td").DATASQUIREL_LoggedInUser | null} * @returns { import("../types/user.td").DATASQUIREL_LoggedInUser | null}
*/ */
function validateToken({ token, encryptionKey, encryptionSalt }) { function validateToken({ token, encryptionKey, encryptionSalt }) {
try { try {
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
const key = token; const key = token;
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
let userPayload = decrypt({ let userPayload = decrypt({
encryptedString: key, encryptedString: key,
encryptionKey, encryptionKey,
encryptionSalt, encryptionSalt,
}); });
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
if (!userPayload) { if (!userPayload) {
return null; return null;
} }
/** /**
* Grab the payload * Grab the payload
* *
* @description Grab the payload * @description Grab the payload
*/ */
let userObject = JSON.parse(userPayload); let userObject = JSON.parse(userPayload);
if (!userObject.csrf_k) { if (!userObject.csrf_k) {
return null; return null;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** /**
* Return User Object * Return User Object
* *
* @description Return User Object * @description Return User Object
*/ */
return userObject; return userObject;
} catch (error) { } catch (error) {
/** /**
* Return User Object * Return User Object
* *
* @description Return User Object * @description Return User Object
*/ */
return null; return null;
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = validateToken; module.exports = validateToken;

View File

@ -1,110 +1,110 @@
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} FunctionReturn * @typedef {Object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {{ * @property {{
* urlPath: string, * urlPath: string,
* urlThumbnailPath: string * urlThumbnailPath: string
* }} payload - Payload containing the url for the image and its thumbnail * }} payload - Payload containing the url for the image and its thumbnail
* @property {string} [msg] - An optional message * @property {string} [msg] - An optional message
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single Param object containing params * @param {Object} params - Single Param object containing params
* @param {String} params.key - *FULL ACCESS API Key * @param {String} params.key - *FULL ACCESS API Key
* @param { string } params.url - File URL * @param { string } params.url - File URL
* *
* @returns { Promise<FunctionReturn> } - Image Url * @returns { Promise<FunctionReturn> } - Image Url
*/ */
async function uploadImage({ key, url }) { async function uploadImage({ key, url }) {
try { try {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify({ url: url }); const reqPayload = JSON.stringify({ url: url });
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/query/delete-file`, path: `/api/query/delete-file`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
console.log("Error deleting file: ", error.message); console.log("Error deleting file: ", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
msg: error.message, msg: error.message,
}; };
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = uploadImage; module.exports = uploadImage;

View File

@ -1,69 +1,69 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const http = require("http"); const http = require("http");
/** /**
* Parse request cookies * Parse request cookies
* ============================================================================== * ==============================================================================
* *
* @description This function takes in a request object and returns the cookies as a JS object * @description This function takes in a request object and returns the cookies as a JS object
* *
* @async * @async
* *
* @param {object} params - main params object * @param {object} params - main params object
* @param {http.IncomingMessage} params.request - HTTPS request object * @param {http.IncomingMessage} params.request - HTTPS request object
* *
* @returns {* | null} * @returns {* | null}
*/ */
module.exports = function ({ request }) { module.exports = function ({ request }) {
/** /**
* Check inputs * Check inputs
* *
* @description Check inputs * @description Check inputs
*/ */
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** @type {string | undefined} */ /** @type {string | undefined} */
const cookieString = request.headers.cookie; const cookieString = request.headers.cookie;
if (!cookieString || typeof cookieString !== "string") { if (!cookieString || typeof cookieString !== "string") {
return null; return null;
} }
/** @type {string[]} */ /** @type {string[]} */
const cookieSplitArray = cookieString.split(";"); const cookieSplitArray = cookieString.split(";");
/** @type {*} */ /** @type {*} */
let cookieObject = {}; let cookieObject = {};
cookieSplitArray.forEach((keyValueString) => { cookieSplitArray.forEach((keyValueString) => {
const [key, value] = keyValueString.split("="); const [key, value] = keyValueString.split("=");
if (key && typeof key == "string") { if (key && typeof key == "string") {
cookieObject[key.replace(/^ +| +$/, "")] = value && typeof value == "string" ? value.replace(/^ +| +$/, "") : null; cookieObject[key.replace(/^ +| +$/, "")] = value && typeof value == "string" ? value.replace(/^ +| +$/, "") : null;
} }
}); });
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
return cookieObject; return cookieObject;
}; };
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////

View File

@ -1,184 +1,184 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* Sanitize SQL function * Sanitize SQL function
* ============================================================================== * ==============================================================================
* @description this function takes in a text(or number) or object or array or * @description this function takes in a text(or number) or object or array or
* boolean and returns a sanitized version of the same input. * boolean and returns a sanitized version of the same input.
* *
* @param {string|number|object|boolean} input - Text or number or object or boolean * @param {string|number|object|boolean} input - Text or number or object or boolean
* @param {boolean?} spaces - Allow spaces? * @param {boolean?} spaces - Allow spaces?
* *
* @returns {string|number|object|boolean} * @returns {string|number|object|boolean}
*/ */
function sanitizeSql(input, spaces) { function sanitizeSql(input, spaces) {
/** /**
* Initial Checks * Initial Checks
* *
* @description Initial Checks * @description Initial Checks
*/ */
if (!input) return ""; if (!input) return "";
if (typeof input == "number" || typeof input == "boolean") return input; if (typeof input == "number" || typeof input == "boolean") return input;
if (typeof input == "string" && !input?.toString()?.match(/./)) return ""; if (typeof input == "string" && !input?.toString()?.match(/./)) return "";
if (typeof input == "object" && !Array.isArray(input)) { if (typeof input == "object" && !Array.isArray(input)) {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const newObject = sanitizeObjects(input, spaces); const newObject = sanitizeObjects(input, spaces);
return newObject; return newObject;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} else if (typeof input == "object" && Array.isArray(input)) { } else if (typeof input == "object" && Array.isArray(input)) {
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
const newArray = sanitizeArrays(input, spaces); const newArray = sanitizeArrays(input, spaces);
return newArray; return newArray;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} }
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
/** /**
* Declare variables * Declare variables
* *
* @description Declare "results" variable * @description Declare "results" variable
*/ */
let finalText = input; let finalText = input;
if (spaces) { if (spaces) {
} else { } else {
finalText = input finalText = input
.toString() .toString()
.replace(/\n|\r|\n\r|\r\n/g, "") .replace(/\n|\r|\n\r|\r\n/g, "")
.replace(/ /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; 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 finalText = finalText
.replace(/(?<!\\)\'/g, "\\'") .replace(/(?<!\\)\'/g, "\\'")
.replace(/(?<!\\)\`/g, "\\`") .replace(/(?<!\\)\`/g, "\\`")
// .replace(/(?<!\\)\"/g, '\\"') // .replace(/(?<!\\)\"/g, '\\"')
.replace(/\/\*\*\//g, "") .replace(/\/\*\*\//g, "")
.replace(escapeRegex, "\\$&"); .replace(escapeRegex, "\\$&");
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
return finalText; return finalText;
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
//////////////////////////////////////// ////////////////////////////////////////
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* Sanitize Objects Function * Sanitize Objects Function
* ============================================================================== * ==============================================================================
* @description Sanitize objects in the form { key: "value" } * @description Sanitize objects in the form { key: "value" }
* *
* @param {object} object - Database Full Name * @param {object} object - Database Full Name
* @param {boolean?} spaces - Allow spaces * @param {boolean?} spaces - Allow spaces
* *
* @returns {object} * @returns {object}
*/ */
function sanitizeObjects(object, spaces) { function sanitizeObjects(object, spaces) {
let objectUpdated = { ...object }; let objectUpdated = { ...object };
const keys = Object.keys(objectUpdated); const keys = Object.keys(objectUpdated);
keys.forEach((key) => { keys.forEach((key) => {
const value = objectUpdated[key]; const value = objectUpdated[key];
if (!value) { if (!value) {
delete objectUpdated[key]; delete objectUpdated[key];
return; return;
} }
if (typeof value == "string" || typeof value == "number") { if (typeof value == "string" || typeof value == "number") {
objectUpdated[key] = sanitizeSql(value, spaces); objectUpdated[key] = sanitizeSql(value, spaces);
} else if (typeof value == "object" && !Array.isArray(value)) { } else if (typeof value == "object" && !Array.isArray(value)) {
objectUpdated[key] = sanitizeObjects(value, spaces); objectUpdated[key] = sanitizeObjects(value, spaces);
} else if (typeof value == "object" && Array.isArray(value)) { } else if (typeof value == "object" && Array.isArray(value)) {
objectUpdated[key] = sanitizeArrays(value, spaces); objectUpdated[key] = sanitizeArrays(value, spaces);
} }
}); });
return objectUpdated; return objectUpdated;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/** /**
* Sanitize Objects Function * Sanitize Objects Function
* ============================================================================== * ==============================================================================
* @description Sanitize objects in the form { key: "value" } * @description Sanitize objects in the form { key: "value" }
* *
* @param {string[]|number[]|object[]} array - Database Full Name * @param {string[]|number[]|object[]} array - Database Full Name
* @param {boolean?} spaces - Allow spaces * @param {boolean?} spaces - Allow spaces
* *
* @returns {string[]|number[]|object[]} * @returns {string[]|number[]|object[]}
*/ */
function sanitizeArrays(array, spaces) { function sanitizeArrays(array, spaces) {
let arrayUpdated = [...array]; let arrayUpdated = [...array];
arrayUpdated.forEach((item, index) => { arrayUpdated.forEach((item, index) => {
const value = item; const value = item;
if (!value) { if (!value) {
arrayUpdated.splice(index, 1); arrayUpdated.splice(index, 1);
return; return;
} }
if (typeof item == "string" || typeof item == "number") { if (typeof item == "string" || typeof item == "number") {
arrayUpdated[index] = sanitizeSql(value, spaces); arrayUpdated[index] = sanitizeSql(value, spaces);
} else if (typeof item == "object" && !Array.isArray(value)) { } else if (typeof item == "object" && !Array.isArray(value)) {
arrayUpdated[index] = sanitizeObjects(value, spaces); arrayUpdated[index] = sanitizeObjects(value, spaces);
} else if (typeof item == "object" && Array.isArray(value)) { } else if (typeof item == "object" && Array.isArray(value)) {
arrayUpdated[index] = sanitizeArrays(item, spaces); arrayUpdated[index] = sanitizeArrays(item, spaces);
} }
}); });
return arrayUpdated; return arrayUpdated;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
module.exports = sanitizeSql; module.exports = sanitizeSql;

View File

@ -1,89 +1,89 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} GetSchemaReturn * @typedef {Object} GetSchemaReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {import("../types/database-schema.td").DSQL_DatabaseSchemaType[] | import("../types/database-schema.td").DSQL_DatabaseSchemaType | null} payload - Response payload * @property {import("../types/database-schema.td").DSQL_DatabaseSchemaType[] | import("../types/database-schema.td").DSQL_DatabaseSchemaType | null} payload - Response payload
*/ */
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {string} params.key - `FULL ACCESS` API Key * @param {string} params.key - `FULL ACCESS` API Key
* @param {string} [params.database] - The database schema to get * @param {string} [params.database] - The database schema to get
* *
* @returns { Promise<GetSchemaReturn> } - Return Object * @returns { Promise<GetSchemaReturn> } - Return Object
*/ */
async function getSchema({ key, database }) { async function getSchema({ key, database }) {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
https https
.request( .request(
{ {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: "/api/query/get-schema" + (database ? `?database=${database}` : ""), path: "/api/query/get-schema" + (database ? `?database=${database}` : ""),
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
) )
.end(); .end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = getSchema; module.exports = getSchema;

View File

@ -1,134 +1,134 @@
// @ts-check // @ts-check
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
const localGet = require("../engine/query/get"); const localGet = require("../engine/query/get");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} GetReturn * @typedef {Object} GetReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {*} [payload] - GET request results * @property {*} [payload] - GET request results
* @property {string} [msg] - Message * @property {string} [msg] - Message
* @property {string} [error] - Error Message * @property {string} [error] - Error Message
*/ */
/** /**
* Make a get request to Datasquirel API * Make a get request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {string} [params.key] - API Key * @param {string} [params.key] - API Key
* @param {string} [params.db] - Database Name * @param {string} [params.db] - Database Name
* @param {string} params.query - SQL Query * @param {string} params.query - SQL Query
* @param {string[]} [params.queryValues] - An array of query values if using "?" placeholders * @param {string[]} [params.queryValues] - An array of query values if using "?" placeholders
* @param {string} [params.tableName] - Name of the table to query * @param {string} [params.tableName] - Name of the table to query
* *
* @returns { Promise<GetReturn> } - Return Object * @returns { Promise<GetReturn> } - Return Object
*/ */
async function get({ key, db, query, queryValues, tableName }) { async function get({ key, db, query, queryValues, tableName }) {
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
return await localGet({ return await localGet({
dbSchema: dbSchema, dbSchema: dbSchema,
options: { options: {
query: query, query: query,
queryValues: queryValues, queryValues: queryValues,
tableName: tableName, tableName: tableName,
}, },
}); });
} }
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
let path = `/api/query/get?db=${db}&query=${query let path = `/api/query/get?db=${db}&query=${query
.replace(/\n|\r|\n\r/g, "") .replace(/\n|\r|\n\r/g, "")
.replace(/ {2,}/g, " ") .replace(/ {2,}/g, " ")
.replace(/ /g, "+")}`; .replace(/ /g, "+")}`;
if (queryValues) { if (queryValues) {
path += `&queryValues=${JSON.stringify(queryValues)}${tableName ? `&tableName=${tableName}` : ""}`; path += `&queryValues=${JSON.stringify(queryValues)}${tableName ? `&tableName=${tableName}` : ""}`;
} }
https https
.request( .request(
{ {
method: "GET", method: "GET",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: path, path: path,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
) )
.end(); .end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = get; module.exports = get;

View File

@ -1,181 +1,181 @@
// @ts-check // @ts-check
/** /**
* Imports * Imports
*/ */
const https = require("https"); const https = require("https");
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
const localPost = require("../engine/query/post"); const localPost = require("../engine/query/post");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} PostReturn * @typedef {Object} PostReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {(Object[]|string)} [payload=[]] - The Y Coordinate * @property {(Object[]|string)} [payload=[]] - The Y Coordinate
*/ */
/** /**
* @typedef {object} PostDataPayload * @typedef {object} PostDataPayload
* @property {"insert" | "update" | "delete"} action - The target action to take * @property {"insert" | "update" | "delete"} action - The target action to take
* @property {string} table - Table name(slug) eg "blog_posts" * @property {string} table - Table name(slug) eg "blog_posts"
* @property {object} [data] - Table insert payload object => This must have keys that match * @property {object} [data] - Table insert payload object => This must have keys that match
* table fields * table fields
* @property {string?} [identifierColumnName] - Table identifier field name => eg. "id" OR "email" * @property {string?} [identifierColumnName] - Table identifier field name => eg. "id" OR "email"
* @property {string?} [identifierValue] - Corresponding value of the selected field name => This * @property {string?} [identifierValue] - Corresponding value of the selected field name => This
* checks identifies a the target row for "update" or "delete". Not needed for "insert" * checks identifies a the target row for "update" or "delete". Not needed for "insert"
* @property {string?} [duplicateColumnName] - Duplicate column name to check for * @property {string?} [duplicateColumnName] - Duplicate column name to check for
* @property {string?} [duplicateColumnValue] - Duplicate column value to match. If no "update" param * @property {string?} [duplicateColumnValue] - Duplicate column value to match. If no "update" param
* provided, function will return null * provided, function will return null
* @property {boolean?} [update] - Should the "insert" action update the existing entry if indeed * @property {boolean?} [update] - Should the "insert" action update the existing entry if indeed
* the entry with "duplicateColumnValue" exists? * the entry with "duplicateColumnValue" exists?
*/ */
/** /**
* Make a post request to Datasquirel API * Make a post request to Datasquirel API
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single object passed * @param {Object} params - Single object passed
* @param {string} [params.key] - FULL ACCESS API Key * @param {string} [params.key] - FULL ACCESS API Key
* @param {string} [params.database] - Database Name * @param {string} [params.database] - Database Name
* @param {PostDataPayload | string} params.query - SQL query String or Request Object * @param {PostDataPayload | string} params.query - SQL query String or Request Object
* @param {any[]} [params.queryValues] - Query Values if using "?" placeholders * @param {any[]} [params.queryValues] - Query Values if using "?" placeholders
* @param {string} [params.tableName] - Name of the table to query * @param {string} [params.tableName] - Name of the table to query
* *
* @returns { Promise<PostReturn> } - Return Object * @returns { Promise<PostReturn> } - Return Object
*/ */
async function post({ key, query, queryValues, database, tableName }) { async function post({ key, query, queryValues, database, tableName }) {
/** /**
* Check for local DB settings * Check for local DB settings
* *
* @description Look for local db settings in `.env` file and by pass the http request if available * @description Look for local db settings in `.env` file and by pass the http request if available
*/ */
const { DSQL_HOST, DSQL_USER, DSQL_PASS, DSQL_DB_NAME, DSQL_KEY, DSQL_REF_DB_NAME, DSQL_FULL_SYNC } = process.env; const { DSQL_HOST, DSQL_USER, DSQL_PASS, 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_NAME?.match(/./)) { if (DSQL_HOST?.match(/./) && DSQL_USER?.match(/./) && DSQL_PASS?.match(/./) && DSQL_DB_NAME?.match(/./)) {
/** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */ /** @type {import("../types/database-schema.td").DSQL_DatabaseSchemaType | undefined} */
let dbSchema; let dbSchema;
try { try {
const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json"); const localDbSchemaPath = path.resolve(process.cwd(), "dsql.schema.json");
dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8")); dbSchema = JSON.parse(fs.readFileSync(localDbSchemaPath, "utf8"));
} catch (error) {} } catch (error) {}
console.log("Reading from local database ..."); console.log("Reading from local database ...");
return await localPost({ return await localPost({
dbSchema: dbSchema, dbSchema: dbSchema,
options: { options: {
query: query, query: query,
queryValues: queryValues, queryValues: queryValues,
tableName: tableName, tableName: tableName,
}, },
}); });
} }
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayloadString = JSON.stringify({ const reqPayloadString = JSON.stringify({
query, query,
queryValues, queryValues,
database, database,
tableName: tableName ? tableName : null, tableName: tableName ? tableName : null,
}).replace(/\n|\r|\n\r/gm, ""); }).replace(/\n|\r|\n\r/gm, "");
try { try {
JSON.parse(reqPayloadString); JSON.parse(reqPayloadString);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
console.log(reqPayloadString); console.log(reqPayloadString);
return { return {
success: false, success: false,
payload: null, payload: null,
error: "Query object is invalid. Please Check query data values", error: "Query object is invalid. Please Check query data values",
}; };
} }
const reqPayload = reqPayloadString; const reqPayload = reqPayloadString;
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/query/post`, path: `/api/query/post`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
try { try {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
} catch (error) { } catch (error) {
console.log(error); console.log(error);
console.log("Fetched Payload =>", str); console.log("Fetched Payload =>", str);
resolve({ resolve({
success: false, success: false,
payload: null, payload: null,
error: error, error: error,
}); });
} }
}); });
response.on("error", (err) => { response.on("error", (err) => {
resolve({ resolve({
success: false, success: false,
payload: null, payload: null,
error: err.message, error: err.message,
}); });
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.on("error", (error) => { httpsRequest.on("error", (error) => {
console.log("HTTPS request ERROR =>", error); console.log("HTTPS request ERROR =>", error);
}); });
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = post; module.exports = post;

View File

@ -1,115 +1,115 @@
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} FunctionReturn * @typedef {Object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {{ * @property {{
* urlPath: string, * urlPath: string,
* }} payload - Payload containing the url for the image and its thumbnail * }} payload - Payload containing the url for the image and its thumbnail
* @property {string} [msg] - An optional message * @property {string} [msg] - An optional message
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single Param object containing params * @param {Object} params - Single Param object containing params
* @param {String} params.key - *FULL ACCESS API Key * @param {String} params.key - *FULL ACCESS API Key
* @param {{ * @param {{
* fileData: string, * fileData: string,
* fileName: string, * fileName: string,
* mimeType?: string, * mimeType?: string,
* folder?: string, * folder?: string,
* isPrivate?: boolean, * isPrivate?: boolean,
* }} params.payload - Image Data Eg. * }} params.payload - Image Data Eg.
* *
* @returns { Promise<FunctionReturn> } - Return Object * @returns { Promise<FunctionReturn> } - Return Object
*/ */
async function uploadImage({ key, payload }) { async function uploadImage({ key, payload }) {
try { try {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify(payload); const reqPayload = JSON.stringify(payload);
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/query/add-file`, path: `/api/query/add-file`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
console.log("Error in uploading file: ", error.message); console.log("Error in uploading file: ", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
msg: error.message, msg: error.message,
}; };
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = uploadImage; module.exports = uploadImage;

View File

@ -1,117 +1,117 @@
/** /**
* ============================================================================== * ==============================================================================
* Imports * Imports
* ============================================================================== * ==============================================================================
*/ */
const https = require("https"); const https = require("https");
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** ****************************************************************************** */ /** ****************************************************************************** */
/** /**
* @typedef {Object} FunctionReturn * @typedef {Object} FunctionReturn
* @property {boolean} success - Did the function run successfully? * @property {boolean} success - Did the function run successfully?
* @property {{ * @property {{
* urlPath: string, * urlPath: string,
* urlThumbnailPath: string * urlThumbnailPath: string
* }} payload - Payload containing the url for the image and its thumbnail * }} payload - Payload containing the url for the image and its thumbnail
* @property {string} [msg] - An optional message * @property {string} [msg] - An optional message
*/ */
/** /**
* ============================================================================== * ==============================================================================
* Main Function * Main Function
* ============================================================================== * ==============================================================================
* @async * @async
* *
* @param {Object} params - Single Param object containing params * @param {Object} params - Single Param object containing params
* @param {String} params.key - *FULL ACCESS API Key * @param {String} params.key - *FULL ACCESS API Key
* @param {{ * @param {{
* imageData: string, * imageData: string,
* imageName: string, * imageName: string,
* mimeType?: string, * mimeType?: string,
* thumbnailSize?: number, * thumbnailSize?: number,
* folder?: string, * folder?: string,
* isPrivate?: boolean, * isPrivate?: boolean,
* }} params.payload - Image Data Eg. * }} params.payload - Image Data Eg.
* *
* @returns { Promise<FunctionReturn> } - Return Object * @returns { Promise<FunctionReturn> } - Return Object
*/ */
async function uploadImage({ key, payload }) { async function uploadImage({ key, payload }) {
try { try {
/** /**
* Make https request * Make https request
* *
* @description make a request to datasquirel.com * @description make a request to datasquirel.com
*/ */
const httpResponse = await new Promise((resolve, reject) => { const httpResponse = await new Promise((resolve, reject) => {
const reqPayload = JSON.stringify(payload); const reqPayload = JSON.stringify(payload);
const httpsRequest = https.request( const httpsRequest = https.request(
{ {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Content-Length": Buffer.from(reqPayload).length, "Content-Length": Buffer.from(reqPayload).length,
Authorization: key, Authorization: key,
}, },
port: 443, port: 443,
hostname: "datasquirel.com", hostname: "datasquirel.com",
path: `/api/query/add-image`, path: `/api/query/add-image`,
}, },
/** /**
* Callback Function * Callback Function
* *
* @description https request callback * @description https request callback
*/ */
(response) => { (response) => {
var str = ""; var str = "";
response.on("data", function (chunk) { response.on("data", function (chunk) {
str += chunk; str += chunk;
}); });
response.on("end", function () { response.on("end", function () {
resolve(JSON.parse(str)); resolve(JSON.parse(str));
}); });
response.on("error", (err) => { response.on("error", (err) => {
reject(err); reject(err);
}); });
} }
); );
httpsRequest.write(reqPayload); httpsRequest.write(reqPayload);
httpsRequest.end(); httpsRequest.end();
}); });
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
return httpResponse; return httpResponse;
} catch (/** @type {*} */ error) { } catch (/** @type {*} */ error) {
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
console.log("Error in uploading image: ", error.message); console.log("Error in uploading image: ", error.message);
return { return {
success: false, success: false,
payload: null, payload: null,
msg: error.message, msg: error.message,
}; };
} }
} }
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
/** ********************************************** */ /** ********************************************** */
module.exports = uploadImage; module.exports = uploadImage;