add account settings page, rest of otp support, stdio credential helper, other misc
[squeep-authentication-module] / lib / common.js
1 'use strict';
2
3 const { common } = require('@squeep/api-dingus');
4
5
6 /**
7 * Recursively freeze an object.
8 * @param {Object} o
9 * @returns {Object}
10 */
11 const freezeDeep = (o) => {
12 Object.freeze(o);
13 Object.getOwnPropertyNames(o).forEach((prop) => {
14 if (Object.hasOwn(o, prop)
15 && ['object', 'function'].includes(typeof o[prop]) // eslint-disable-line security/detect-object-injection
16 && !Object.isFrozen(o[prop])) { // eslint-disable-line security/detect-object-injection
17 return freezeDeep(o[prop]); // eslint-disable-line security/detect-object-injection
18 }
19 });
20 return o;
21 };
22
23 /**
24 * Return a new object duplicating `o`, without the properties specified.
25 * @param {Object} o
26 * @param {String[]} props
27 * @returns {Object}
28 */
29 const omit = (o, props) => {
30 return Object.fromEntries(Object.entries(o).filter(([k]) => !props.includes(k)));
31 };
32
33 /**
34 * Helper to log mystery-box statistics.
35 * @param {ConsoleLike} logger
36 * @param {String} scope
37 * @returns {Function}
38 */
39 const mysteryBoxLogger = (logger, scope) => {
40 return (s) => {
41 logger.debug(scope, `${s.packageName}@${s.packageVersion}:${s.method}`, omit(s, [
42 'packageName',
43 'packageVersion',
44 'method',
45 ]));
46 };
47 };
48
49 /**
50 * Hide sensitive part of an Authorization header.
51 * @param {String} authHeader
52 * @returns {String}
53 */
54 const obscureAuthorizationHeader = (authHeader) => {
55 if (!authHeader) {
56 return authHeader;
57 }
58 const space = authHeader.indexOf(' ');
59 // This blurs entire string if no space found, because -1.
60 return authHeader.slice(0, space + 1) + '*'.repeat(authHeader.length - (space + 1));
61 };
62
63 module.exports = Object.assign(Object.create(common), {
64 freezeDeep,
65 mysteryBoxLogger,
66 obscureAuthorizationHeader,
67 omit,
68 });