From 09359b3b9098105fecab52fa1391f933062420ea Mon Sep 17 00:00:00 2001 From: Tben <52448020+BenjaminToby@users.noreply.github.com> Date: Sat, 24 Jun 2023 10:20:05 +0100 Subject: [PATCH] updates --- package.json | 2 +- users/login-user.js | 1 + users/social/google-auth.js | 190 ++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 users/social/google-auth.js diff --git a/package.json b/package.json index 34a7303..1675c2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "datasquirel", - "version": "1.1.40", + "version": "1.1.41", "description": "Cloud-based SQL data management tool", "main": "index.js", "scripts": { diff --git a/users/login-user.js b/users/login-user.js index a42a182..edaeb2b 100644 --- a/users/login-user.js +++ b/users/login-user.js @@ -142,6 +142,7 @@ module.exports = async function ({ key, payload, database, response, encryptionK /** ********************************************** */ /** ********************************************** */ /** ********************************************** */ + /** * Make https request * diff --git a/users/social/google-auth.js b/users/social/google-auth.js new file mode 100644 index 0000000..ef6b064 --- /dev/null +++ b/users/social/google-auth.js @@ -0,0 +1,190 @@ +/** + * ============================================================================== + * Imports + * ============================================================================== + */ +const https = require("https"); +const encrypt = require("../../functions/encrypt"); + +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ +/** ****************************************************************************** */ + +/** + * @typedef {object} FunctionReturn + * @property {boolean} success - Did the function run successfully? + * @property {{id: number, first_name: string, last_name: string}|null} user - Returned User + * @property {string} [msg] - Response message + */ + +/** + * SERVER FUNCTION: Login with google Function + * ============================================================================== + * + * @async + * + * @param {object} params - main params object + * @param {string} params.key - API full access key + * @param {string} params.token - Google access token gotten from the client side + * @param {string} params.database - Target database name(slug) + * @param {string} params.clientId - Google client id + * @param {object} params.response - HTTPS response object + * @param {string} params.encryptionKey - Encryption key + * @param {string} params.encryptionSalt - Encryption salt + * + * @returns { Promise } + */ +module.exports = async function ({ key, token, database, clientId, response, encryptionKey, encryptionSalt }) { + /** + * Check inputs + * + * @description Check inputs + */ + if (!key || key?.match(/ /)) { + return { + success: false, + user: null, + msg: "Please enter API full access Key", + }; + } + + if (!token || token?.match(/ /)) { + return { + success: false, + user: null, + msg: "Please enter Google Access Token", + }; + } + + if (!database || database?.match(/ /)) { + return { + success: false, + user: null, + msg: "Please provide database slug name you want to access", + }; + } + + if (!clientId || clientId?.match(/ /)) { + return { + success: false, + user: null, + msg: "Please enter Google OAUTH client ID", + }; + } + + if (!response || !response?.setHeader) { + return { + success: false, + user: null, + msg: "Please provide a valid HTTPS response object", + }; + } + + if (!encryptionKey || encryptionKey?.match(/ /)) { + return { + success: false, + user: null, + msg: "Please provide a valid encryption key", + }; + } + + if (!encryptionSalt || encryptionSalt?.match(/ /)) { + return { + success: false, + user: null, + msg: "Please provide a valid encryption salt", + }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + + /** + * Make https request + * + * @description make a request to datasquirel.com + * @type {{ success: boolean, user: {id: number} | null, msg: string|null } | null} - Https response object + */ + const httpResponse = await new Promise((resolve, reject) => { + const reqPayload = JSON.stringify({ + token, + clientId, + database, + }); + + const httpsRequest = https.request( + { + method: "POST", + headers: { + "Content-Type": "application/json", + "Content-Length": Buffer.from(reqPayload).length, + Authorization: key, + }, + port: 443, + hostname: "datasquirel.com", + path: `/api/user/google-login`, + }, + + /** + * Callback Function + * + * @description https request callback + */ + (response) => { + var str = ""; + + response.on("data", function (chunk) { + str += chunk; + }); + + response.on("end", function () { + resolve(JSON.parse(str)); + }); + + response.on("error", (err) => { + reject(err); + }); + } + ); + httpsRequest.write(reqPayload); + httpsRequest.end(); + }); + + //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + + /** + * Make https request + * + * @description make a request to datasquirel.com + */ + if (httpResponse?.success && httpResponse?.user) { + let encryptedPayload = encrypt({ + data: JSON.stringify(httpResponse.user), + encryptionKey, + encryptionSalt, + }); + + const { user } = httpResponse; + + const authKeyName = `datasquirel_${user.id}_${database}_auth_key`; + const csrfName = `datasquirel_${user.id}_${database}_csrf`; + + response.setHeader("Set-Cookie", [`${authKeyName}=${encryptedPayload};samesite=strict;path=/;HttpOnly=true;Secure=true`, `${csrfName}=${httpResponse.user.csrf_k};samesite=strict;path=/;sHttpOnly=true`, `dsqluid=${user.id};samesite=strict;path=/;HttpOnly=true`]); + } + + //////////////////////////////////////// + //////////////////////////////////////// + //////////////////////////////////////// + + return httpResponse; +}; + +//////////////////////////////////////// +//////////////////////////////////////// +////////////////////////////////////////