X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fcommon.js;h=162b751ef23805d30bbf97eb71a69f367adf3d59;hb=refs%2Ftags%2Fv2.1.0;hp=f839e7a05cf16790779a75a2d6c15d19689d9f98;hpb=914e78e62c740792ed7f6de319360ea4aa60c67e;p=squeep-api-dingus diff --git a/lib/common.js b/lib/common.js index f839e7a..162b751 100644 --- a/lib/common.js +++ b/lib/common.js @@ -5,29 +5,10 @@ * Utility and miscellaneous functions. */ -const path = require('path'); -const crypto = require('crypto'); +const crypto = require('node:crypto'); const uuid = require('uuid'); const Enum = require('./enum'); - -/** - * @callback ScopeFn - * @param {String} scope - * @returns {String} - */ -/** - * Return a function which prefixes a provided scope with the most- - * relevant part of the filename, for use in logging. - * @param {String} filename - * @returns {ScopeFn} - */ -const fileScope = (filename) => { - let fScope = path.basename(filename, '.js'); - if (fScope === 'index') { - fScope = path.basename(path.dirname(filename)); - } - return (scope) => `${fScope}:${scope}`; -}; +const { fileScope } = require('@squeep/log-helper'); /** * Simple ETag from data. @@ -213,7 +194,68 @@ const unfoldHeaderLines = (lines) => { return lines; }; +/** + * Adds a new cookie. + * @param {http.ServerResponse} res + * @param {String} name + * @param {String} value + * @param {Object=} opt + * @param {String=} opt.domain + * @param {Date=} opt.expires + * @param {Boolean=} opt.httpOnly + * @param {Number=} opt.maxAge + * @param {String=} opt.path + * @param {String=} opt.sameSite + * @param {Boolean=} opt.secure + */ +function addCookie(res, name, value, opt = {}) { + const options = { + domain: undefined, + expires: undefined, + httpOnly: false, + maxAge: undefined, + path: undefined, + sameSite: undefined, + secure: false, + ...opt, + }; + // TODO: validate name, value + const cookieParts = [ + `${name}=${value}`, + ]; + if (options.domain) { + cookieParts.push(`Domain=${options.domain}`); + } + if (options.expires) { + if (!(options.expires instanceof Date)) { + throw new TypeError('cookie expires must be Date'); + } + cookieParts.push(`Expires=${options.expires.toUTCString()}`); + } + if (options.httpOnly) { + cookieParts.push('HttpOnly'); + } + if (options.maxAge) { + cookieParts.push(`Max-Age=${options.maxAge}`); + } + if (options.path) { + cookieParts.push(`Path=${options.path}`); + } + if (options.sameSite) { + if (!(['Strict', 'Lax', 'None'].includes(options.sameSite))) { + throw new RangeError('cookie sameSite value not valid'); + } + cookieParts.push(`SameSite=${options.sameSite}`); + } + if (options.secure) { + cookieParts.push('Secure'); + } + res.appendHeader(Enum.Header.SetCookie, cookieParts.join('; ')); +} + + module.exports = { + addCookie, fileScope, generateETag, get,