Updates
This commit is contained in:
@@ -37,13 +37,11 @@
|
||||
},
|
||||
{
|
||||
"fieldName": "image",
|
||||
"dataType": "VARCHAR(250)",
|
||||
"defaultValue": "/images/user-preset.png"
|
||||
"dataType": "VARCHAR(250)"
|
||||
},
|
||||
{
|
||||
"fieldName": "image_thumbnail",
|
||||
"dataType": "VARCHAR(250)",
|
||||
"defaultValue": "/images/user-preset-thumbnail.png"
|
||||
"dataType": "VARCHAR(250)"
|
||||
},
|
||||
{
|
||||
"fieldName": "address",
|
||||
|
||||
@@ -128,8 +128,12 @@ module.exports = async function apiCreateUser({
|
||||
tableName: "users",
|
||||
data: {
|
||||
...payload,
|
||||
image: "/images/user-preset.png",
|
||||
image_thumbnail: "/images/user-preset-thumbnail.png",
|
||||
image:
|
||||
process.env.DSQL_DEFAULT_USER_IMAGE ||
|
||||
"/images/user-preset.png",
|
||||
image_thumbnail:
|
||||
process.env.DSQL_DEFAULT_USER_IMAGE ||
|
||||
"/images/user-preset-thumbnail.png",
|
||||
},
|
||||
useLocal,
|
||||
});
|
||||
|
||||
@@ -103,8 +103,8 @@ module.exports = async function apiLoginUser({
|
||||
|
||||
if (isPasswordCorrect && email_login) {
|
||||
const resetTempCode = await varDatabaseDbHandler({
|
||||
queryString: `UPDATE users SET ${email_login_field} = ? WHERE email = ? OR username = ?`,
|
||||
queryValuesArray: ["", email, username],
|
||||
queryString: `UPDATE users SET ${email_login_field} = '' WHERE email = ? OR username = ?`,
|
||||
queryValuesArray: [email, username],
|
||||
database: dbFullName.replace(/[^a-z0-9_]/g, ""),
|
||||
useLocal,
|
||||
});
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
const LOCAL_DB_HANDLER = require("../../../utils/backend/global-db/LOCAL_DB_HANDLER");
|
||||
const varDatabaseDbHandler = require("../../backend/varDatabaseDbHandler");
|
||||
const nodemailer = require("nodemailer");
|
||||
const http = require("http");
|
||||
const getAuthCookieNames = require("../../backend/cookies/get-auth-cookie-names");
|
||||
const encrypt = require("../../dsql/encrypt");
|
||||
const serializeCookies = require("../../../utils/serialize-cookies");
|
||||
|
||||
/**
|
||||
* # Send Email Login Code
|
||||
@@ -18,8 +21,10 @@ const nodemailer = require("nodemailer");
|
||||
* @param {string} [param.mail_password]
|
||||
* @param {string} param.html
|
||||
* @param {boolean} [param.useLocal]
|
||||
* @param {http.ServerResponse & Object<string,any>} [param.response]
|
||||
* @param {import("../../../../package-shared/types").CookieObject[]} [param.extraCookies]
|
||||
*
|
||||
* @returns {Promise<{success: boolean, msg?: string}>}
|
||||
* @returns {Promise<import("../../../types").SendOneTimeCodeEmailResponse>}
|
||||
*/
|
||||
module.exports = async function apiSendEmailCode({
|
||||
email,
|
||||
@@ -32,6 +37,8 @@ module.exports = async function apiSendEmailCode({
|
||||
mail_password,
|
||||
html,
|
||||
useLocal,
|
||||
response,
|
||||
extraCookies,
|
||||
}) {
|
||||
if (email?.match(/ /)) {
|
||||
return {
|
||||
@@ -39,10 +46,7 @@ module.exports = async function apiSendEmailCode({
|
||||
msg: "Invalid Email/Password format",
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
const createdAt = Date.now();
|
||||
|
||||
const foundUserQuery = `SELECT * FROM users WHERE email = ?`;
|
||||
const foundUserValues = [email];
|
||||
@@ -74,12 +78,12 @@ module.exports = async function apiSendEmailCode({
|
||||
return code;
|
||||
}
|
||||
|
||||
if (foundUser && foundUser[0] && email_login_field) {
|
||||
if (foundUser?.[0] && email_login_field) {
|
||||
const tempCode = generateCode();
|
||||
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: mail_domain || process.env.DSQL_MAIL_HOST,
|
||||
port: mail_port || 465,
|
||||
port: mail_port || process.env.DSQL_MAIL_PORT || 465,
|
||||
secure: true,
|
||||
auth: {
|
||||
user: mail_username || process.env.DSQL_MAIL_EMAIL,
|
||||
@@ -102,7 +106,7 @@ module.exports = async function apiSendEmailCode({
|
||||
if (!info?.accepted) throw new Error("Mail not Sent!");
|
||||
|
||||
const setTempCodeQuery = `UPDATE users SET ${email_login_field} = ? WHERE email = ?`;
|
||||
const setTempCodeValues = [tempCode + `-${Date.now()}`, email];
|
||||
const setTempCodeValues = [tempCode + `-${createdAt}`, email];
|
||||
|
||||
let setTempCode = await varDatabaseDbHandler({
|
||||
queryString: setTempCodeQuery,
|
||||
@@ -110,10 +114,57 @@ module.exports = async function apiSendEmailCode({
|
||||
database: database,
|
||||
useLocal,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
msg: "Success",
|
||||
};
|
||||
/** @type {import("../../../types").SendOneTimeCodeEmailResponse} */
|
||||
const resObject = {
|
||||
success: true,
|
||||
code: tempCode,
|
||||
email: email,
|
||||
createdAt,
|
||||
msg: "Success",
|
||||
};
|
||||
|
||||
if (response) {
|
||||
const cookieKeyNames = getAuthCookieNames();
|
||||
const oneTimeCodeCookieName = cookieKeyNames.oneTimeCodeName;
|
||||
|
||||
const encryptedPayload = encrypt({
|
||||
data: JSON.stringify(resObject),
|
||||
});
|
||||
|
||||
if (!encryptedPayload) {
|
||||
throw new Error(
|
||||
"apiSendEmailCode Error: Failed to encrypt payload"
|
||||
);
|
||||
}
|
||||
|
||||
/** @type {import("../../../../package-shared/types").CookieObject} */
|
||||
const oneTimeCookieObject = {
|
||||
name: oneTimeCodeCookieName,
|
||||
value: encryptedPayload,
|
||||
sameSite: "Strict",
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
};
|
||||
|
||||
/** @type {import("../../../../package-shared/types").CookieObject[]} */
|
||||
const cookiesObjectArray = extraCookies
|
||||
? [...extraCookies, oneTimeCookieObject]
|
||||
: [oneTimeCookieObject];
|
||||
|
||||
const serializedCookies = serializeCookies({
|
||||
cookies: cookiesObjectArray,
|
||||
});
|
||||
|
||||
response.setHeader("Set-Cookie", serializedCookies);
|
||||
}
|
||||
|
||||
return resObject;
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
msg: "Invalid Email/Password format",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ const camelJoinedtoCamelSpace = require("../../../../utils/camelJoinedtoCamelSpa
|
||||
* @param {string} [param.email]
|
||||
* @param {string | number} [param.userId]
|
||||
*
|
||||
* @returns {Promise<import("../../../../types").APIGoogleLoginFunctionReturn>}
|
||||
* @returns {Promise<import("../../../../types").APILoginFunctionReturn>}
|
||||
*/
|
||||
module.exports = async function apiGithubLogin({
|
||||
code,
|
||||
|
||||
@@ -45,7 +45,7 @@ module.exports = async function apiGoogleLogin({
|
||||
if (!database || typeof database != "string" || database?.match(/ /)) {
|
||||
return {
|
||||
success: false,
|
||||
user: undefined,
|
||||
payload: undefined,
|
||||
msg: "Please provide a database slug(database name in lowercase with no spaces)",
|
||||
};
|
||||
}
|
||||
@@ -89,7 +89,7 @@ module.exports = async function apiGoogleLogin({
|
||||
|
||||
return {
|
||||
success: false,
|
||||
user: undefined,
|
||||
payload: undefined,
|
||||
msg: error.message,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ const fs = require("fs");
|
||||
const decrypt = require("../dsql/decrypt");
|
||||
|
||||
/** @type {import("../../types").CheckApiCredentialsFn} */
|
||||
const grabApiCred = ({ key, database, table, user_id }) => {
|
||||
const grabApiCred = ({ key, database, table, user_id, media }) => {
|
||||
if (!key) return null;
|
||||
if (!user_id) return null;
|
||||
|
||||
@@ -27,6 +27,8 @@ const grabApiCred = ({ key, database, table, user_id }) => {
|
||||
|
||||
if (!isApiKeyValid) return null;
|
||||
if (!ApiObject.target_database) return ApiObject;
|
||||
if (media) return ApiObject;
|
||||
|
||||
if (!database && ApiObject.target_database) return null;
|
||||
const isDatabaseAllowed = ApiObject.target_database
|
||||
?.split(",")
|
||||
@@ -41,7 +43,7 @@ const grabApiCred = ({ key, database, table, user_id }) => {
|
||||
return null;
|
||||
} catch (/** @type {any} */ error) {
|
||||
console.log(`api-cred ERROR: ${error.message}`);
|
||||
return null;
|
||||
return { error: `api-cred ERROR: ${error.message}` };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const grabAuthDirs = () => {
|
||||
const ROOT_DIR = path.resolve(process.cwd(), "./.tmp");
|
||||
const DSQL_AUTH_DIR = process.env.DSQL_AUTH_DIR;
|
||||
const ROOT_DIR = DSQL_AUTH_DIR?.match(/./)
|
||||
? DSQL_AUTH_DIR
|
||||
: path.resolve(process.cwd(), "./.tmp");
|
||||
const AUTH_DIR = path.join(ROOT_DIR, "logins");
|
||||
|
||||
return { root: ROOT_DIR, auth: AUTH_DIR };
|
||||
|
||||
@@ -7,15 +7,17 @@
|
||||
* @param {string} [params.database]
|
||||
* @param {string | number} [params.userId]
|
||||
*
|
||||
* @returns {{ keyCookieName: string, csrfCookieName: string }}
|
||||
* @returns {{ keyCookieName: string, csrfCookieName: string, oneTimeCodeName: string }}
|
||||
*/
|
||||
module.exports = function getAuthCookieNames(params) {
|
||||
const cookiesPrefix = process.env.DSQL_COOKIES_PREFIX || "dsql_";
|
||||
const cookiesKeyName = process.env.DSQL_COOKIES_KEY_NAME || "key";
|
||||
const cookiesCSRFName = process.env.DSQL_COOKIES_CSRF_NAME || "csrf";
|
||||
const cookieOneTimeCodeName =
|
||||
process.env.DSQL_COOKIES_ONE_TIME_CODE_NAME || "one-time-code";
|
||||
|
||||
const targetDatabase =
|
||||
params?.database ||
|
||||
params?.database?.replace(/^datasquirel_user_\d+_/, "") ||
|
||||
process.env.DSQL_DB_NAME?.replace(/^datasquirel_user_\d+_/, "");
|
||||
|
||||
let keyCookieName = cookiesPrefix;
|
||||
@@ -28,8 +30,14 @@ module.exports = function getAuthCookieNames(params) {
|
||||
if (targetDatabase) csrfCookieName += `${targetDatabase}_`;
|
||||
csrfCookieName += cookiesCSRFName;
|
||||
|
||||
let oneTimeCodeName = cookiesPrefix;
|
||||
if (params?.userId) oneTimeCodeName += `user_${params.userId}_`;
|
||||
if (targetDatabase) oneTimeCodeName += `${targetDatabase}_`;
|
||||
oneTimeCodeName += cookieOneTimeCodeName;
|
||||
|
||||
return {
|
||||
keyCookieName,
|
||||
csrfCookieName,
|
||||
oneTimeCodeName,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
const sanitizeHtml = require("sanitize-html");
|
||||
const sanitizeHtmlOptions = require("../html/sanitizeHtmlOptions");
|
||||
const updateDb = require("./updateDbEntry");
|
||||
const updateDbEntry = require("./updateDbEntry");
|
||||
const _ = require("lodash");
|
||||
const DB_HANDLER = require("../../../utils/backend/global-db/DB_HANDLER");
|
||||
@@ -160,7 +159,9 @@ async function addDbEntry({
|
||||
console.log("DSQL: Encrypted value =>", value);
|
||||
}
|
||||
|
||||
if (targetFieldSchema?.richText) {
|
||||
const htmlRegex = /<[^>]+>/g;
|
||||
|
||||
if (targetFieldSchema?.richText || String(value).match(htmlRegex)) {
|
||||
value = sanitizeHtml(value, sanitizeHtmlOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,9 @@ async function updateDbEntry({
|
||||
|
||||
if (value == null || value == undefined) continue;
|
||||
|
||||
if (targetFieldSchema?.richText) {
|
||||
const htmlRegex = /<[^>]+>/g;
|
||||
|
||||
if (targetFieldSchema?.richText || String(value).match(htmlRegex)) {
|
||||
value = sanitizeHtml(value, sanitizeHtmlOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ const path = require("path");
|
||||
* @param {string | number} params.userId
|
||||
* @returns {import("../../types").DSQL_DatabaseSchemaType[] | null}
|
||||
*/
|
||||
export default function grabUserSchemaData({ userId }) {
|
||||
module.exports = function grabUserSchemaData({ userId }) {
|
||||
try {
|
||||
const userSchemaFilePath = path.resolve(
|
||||
process.cwd(),
|
||||
@@ -36,7 +36,7 @@ export default function grabUserSchemaData({ userId }) {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
@@ -18,7 +18,7 @@ const path = require("path");
|
||||
* @param {import("../../types").DSQL_DatabaseSchemaType[]} params.schemaData
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export default function setUserSchemaData({ userId, schemaData }) {
|
||||
module.exports = function setUserSchemaData({ userId, schemaData }) {
|
||||
try {
|
||||
const userSchemaFilePath = path.resolve(
|
||||
process.cwd(),
|
||||
@@ -39,7 +39,7 @@ export default function setUserSchemaData({ userId, schemaData }) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
@@ -188,13 +188,7 @@ export interface GetReqQueryObject {
|
||||
tableName?: string;
|
||||
}
|
||||
|
||||
export type SerializeQueryFnType = (param0: SerializeQueryParams) => string;
|
||||
|
||||
export interface SerializeQueryParams {
|
||||
query: any;
|
||||
}
|
||||
|
||||
// @ts-check
|
||||
export type SerializeQueryFnType = (query: any) => string;
|
||||
|
||||
export type DATASQUIREL_LoggedInUser = {
|
||||
id: number;
|
||||
@@ -1026,12 +1020,13 @@ export interface MYSQL_delegated_user_tables_table_def {
|
||||
}
|
||||
|
||||
export type ApiKeyObject = {
|
||||
user_id: string | number;
|
||||
user_id?: string | number;
|
||||
full_access?: boolean;
|
||||
sign: string;
|
||||
date_code: number;
|
||||
sign?: string;
|
||||
date_code?: number;
|
||||
target_database?: string;
|
||||
target_table?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
export type AddApiKeyRequestBody = {
|
||||
@@ -1050,12 +1045,13 @@ export type CheckApiCredentialsFnParam = {
|
||||
database?: string;
|
||||
table?: string;
|
||||
user_id?: string | number;
|
||||
media?: boolean;
|
||||
};
|
||||
|
||||
export type FetchApiFn = (
|
||||
url: string,
|
||||
options?: FetchApiOptions,
|
||||
contentType?: "json" | "text" | "html" | "blob" | "file"
|
||||
csrf?: boolean
|
||||
) => Promise<any>;
|
||||
|
||||
export type FetchApiOptions = RequestInit & {
|
||||
@@ -1269,13 +1265,9 @@ export type APIGoogleLoginFunctionParams = {
|
||||
additionalFields?: string[];
|
||||
};
|
||||
|
||||
export type APIGoogleLoginFunctionReturn = {
|
||||
dsqlUserId?: number | string;
|
||||
} & HandleSocialDbFunctionReturn;
|
||||
|
||||
export type APIGoogleLoginFunction = (
|
||||
params: APIGoogleLoginFunctionParams
|
||||
) => Promise<APIGoogleLoginFunctionReturn>;
|
||||
) => Promise<APILoginFunctionReturn>;
|
||||
|
||||
/**
|
||||
* Handle Social DB Function
|
||||
@@ -1417,3 +1409,24 @@ export interface AceEditorOptions {
|
||||
wrapBehavioursEnabled?: boolean;
|
||||
wrapMethod?: "code" | "text" | "auto";
|
||||
}
|
||||
|
||||
export type SendOneTimeCodeEmailResponse = {
|
||||
success: boolean;
|
||||
code?: string;
|
||||
createdAt?: number;
|
||||
email?: string;
|
||||
msg?: string;
|
||||
};
|
||||
|
||||
export type CookieObject = {
|
||||
name: string;
|
||||
value: string;
|
||||
domain?: string;
|
||||
path?: string;
|
||||
expires?: Date;
|
||||
maxAge?: number;
|
||||
secure?: boolean;
|
||||
httpOnly?: boolean;
|
||||
sameSite?: "Strict" | "Lax" | "None";
|
||||
priority?: "Low" | "Medium" | "High";
|
||||
};
|
||||
|
||||
@@ -1,60 +1,58 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* Imports
|
||||
* ==============================================================================
|
||||
*/
|
||||
const http = require("http");
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @param {object} params - main params object
|
||||
* @param {http.IncomingMessage} params.request - HTTPS request object
|
||||
* @param {http.IncomingMessage & Object<string, any>} [params.request] - HTTPS request object
|
||||
* @param {string} [params.cookieString]
|
||||
*
|
||||
* @returns {any | null}
|
||||
* @returns {Object<string, string>}
|
||||
*/
|
||||
module.exports = function ({ request }) {
|
||||
/**
|
||||
* Check inputs
|
||||
*
|
||||
* @description Check inputs
|
||||
*/
|
||||
module.exports = function parseCookies({ request, cookieString }) {
|
||||
try {
|
||||
/** @type {string | undefined} */
|
||||
const cookieStr = request
|
||||
? request.headers.cookie
|
||||
: cookieString
|
||||
? cookieString
|
||||
: undefined;
|
||||
|
||||
/** @type {string | undefined} */
|
||||
const cookieString = request.headers.cookie;
|
||||
if (!cookieStr) return {};
|
||||
|
||||
if (!cookieString || typeof cookieString !== "string") {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @type {string[]} */
|
||||
const cookieSplitArray = cookieString.split(";");
|
||||
|
||||
/** @type {*} */
|
||||
let cookieObject = {};
|
||||
|
||||
cookieSplitArray.forEach((keyValueString) => {
|
||||
const [key, value] = keyValueString.split("=");
|
||||
if (key && typeof key == "string") {
|
||||
cookieObject[key.replace(/^ +| +$/, "")] =
|
||||
value && typeof value == "string"
|
||||
? value.replace(/^ +| +$/, "")
|
||||
: null;
|
||||
if (!cookieStr || typeof cookieStr !== "string") {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Make https request
|
||||
*
|
||||
* @description make a request to datasquirel.com
|
||||
*/
|
||||
/** @type {string[]} */
|
||||
const cookieSplitArray = cookieStr.split(";");
|
||||
|
||||
return cookieObject;
|
||||
/** @type {Object<string, string>} */
|
||||
let cookieObject = {};
|
||||
|
||||
cookieSplitArray.forEach((keyValueString) => {
|
||||
const [key, value] = keyValueString.split("=");
|
||||
if (key && typeof key == "string") {
|
||||
const parsedKey = key.replace(/^ +| +$/, "");
|
||||
cookieObject[parsedKey] =
|
||||
value && typeof value == "string"
|
||||
? value.replace(/^ +| +$/, "")
|
||||
: "";
|
||||
}
|
||||
});
|
||||
|
||||
return cookieObject;
|
||||
} catch (/** @type {any} */ error) {
|
||||
console.log(`ERROR parsing cookies: ${error.message}`);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* # Get Number from any input
|
||||
* @param {any} num input
|
||||
* @param {number} [decimals] number of decimals to round to
|
||||
* @returns {number} number or 0 in case of error
|
||||
* @example
|
||||
* numberfy("123") // 123
|
||||
* numberfy("123.456") // 123
|
||||
* numberfy("123.456", 2) // 123.46
|
||||
* numberfy("123.456", 0) // 123
|
||||
* numberfy("123.456", 3) // 123.456
|
||||
*/
|
||||
module.exports = function numberfy(num, decimals) {
|
||||
try {
|
||||
const numberfiedNum = Number(num);
|
||||
if (typeof numberfiedNum !== "number") return 0;
|
||||
if (isNaN(numberfiedNum)) return 0;
|
||||
if (decimals) return Number(numberfiedNum.toFixed(decimals));
|
||||
return Math.round(numberfiedNum);
|
||||
} catch (/** @type {any} */ error) {
|
||||
console.log(`Numberfy ERROR: ${error.message}`);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} params
|
||||
* @param {import("../types").CookieObject[]} params.cookies
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function serializeCookies({ cookies }) {
|
||||
/** @type {string[]} */
|
||||
let cookiesStringsArray = [];
|
||||
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookieObject = cookies[i];
|
||||
let cookieString = `${cookieObject.name}=${cookieObject.value}`;
|
||||
|
||||
if (cookieObject.maxAge) {
|
||||
cookieString += `;Max-Age=${cookieObject.maxAge}`;
|
||||
}
|
||||
if (cookieObject.path) {
|
||||
cookieString += `;Path=${cookieObject.path}`;
|
||||
}
|
||||
if (cookieObject.domain) {
|
||||
cookieString += `;Domain=${cookieObject.domain}`;
|
||||
}
|
||||
if (cookieObject.secure) {
|
||||
cookieString += ";Secure";
|
||||
}
|
||||
if (cookieObject.httpOnly) {
|
||||
cookieString += ";HttpOnly";
|
||||
}
|
||||
if (cookieObject.sameSite) {
|
||||
cookieString += `;SameSite=${cookieObject.sameSite}`;
|
||||
}
|
||||
if (cookieObject.expires) {
|
||||
cookieString += `;expires=${cookieObject.expires}`;
|
||||
}
|
||||
if (cookieObject.priority) {
|
||||
cookieString += `;priority=${cookieObject.priority}`;
|
||||
}
|
||||
|
||||
cookiesStringsArray.push(cookieString);
|
||||
}
|
||||
|
||||
return cookiesStringsArray;
|
||||
}
|
||||
|
||||
module.exports = serializeCookies;
|
||||
@@ -0,0 +1,43 @@
|
||||
// @ts-check
|
||||
|
||||
const EJSON = require("./ejson");
|
||||
|
||||
/** @type {import("../types").SerializeQueryFnType} */
|
||||
function serializeQuery(query) {
|
||||
let str = "?";
|
||||
|
||||
if (typeof query !== "object") {
|
||||
console.log("Invalid Query type");
|
||||
return str;
|
||||
}
|
||||
if (Array.isArray(query)) {
|
||||
console.log("Query is an Array. This is invalid.");
|
||||
return str;
|
||||
}
|
||||
if (!query) {
|
||||
console.log("No Query provided.");
|
||||
return str;
|
||||
}
|
||||
|
||||
const keys = Object.keys(query);
|
||||
|
||||
/** @type {string[]} */
|
||||
const queryArr = [];
|
||||
|
||||
keys.forEach((key) => {
|
||||
if (!key || !query[key]) return;
|
||||
const value = query[key];
|
||||
|
||||
if (typeof value === "object") {
|
||||
const jsonStr = EJSON.stringify(value);
|
||||
queryArr.push(`${key}=${encodeURIComponent(String(jsonStr))}`);
|
||||
} else if (typeof value === "string" || typeof value === "number") {
|
||||
queryArr.push(`${key}=${encodeURIComponent(value)}`);
|
||||
}
|
||||
});
|
||||
|
||||
str += queryArr.join("&");
|
||||
return str;
|
||||
}
|
||||
|
||||
module.exports = serializeQuery;
|
||||
@@ -0,0 +1,27 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* # Return the slug of a string
|
||||
* @param {string} str input
|
||||
* @returns {string} slug or empty string in case of error
|
||||
* @example
|
||||
* slugify("Hello World") // "hello-world"
|
||||
* slugify("Yes!") // "yes"
|
||||
* slugify("Hello!!! World!") // "hello-world"
|
||||
*/
|
||||
module.exports = function slugify(str) {
|
||||
try {
|
||||
return String(str)
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/ {2,}/g, " ")
|
||||
.replace(/ /g, "-")
|
||||
.replace(/[^a-z0-9]/g, "-")
|
||||
.replace(/-{2,}/g, "-")
|
||||
.replace(/^-/, "")
|
||||
.replace(/-$/, "");
|
||||
} catch (/** @type {any} */ error) {
|
||||
console.log(`Slugify ERROR: ${error.message}`);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user