initial commit
[squeep-indie-auther] / src / logger / data-sanitizers.js
1 'use strict';
2
3 /**
4 * Scrub credential from POST login body data.
5 * @param {Object} data
6 * @param {Boolean} sanitize
7 * @returns {Boolean}
8 */
9 function sanitizePostCredential(data, sanitize = true) {
10 let unclean = false;
11
12 const credentialLength = data?.ctx?.parsedBody?.credential?.length;
13 if (credentialLength) {
14 unclean = true;
15 }
16 if (unclean && sanitize) {
17 data.ctx.parsedBody.credential = '*'.repeat(credentialLength);
18 }
19
20 return unclean;
21 }
22
23
24 /**
25 * Reduce logged data about scopes from profilesScopes.
26 * For all referenced scopes, only include profiles list.
27 * Remove scopes without profile references from scopeIndex.
28 * @param {Object} data
29 * @param {Boolean} sanitize
30 */
31 function reduceScopeVerbosity(data, sanitize = true) {
32 let unclean = false;
33
34 const {
35 scopesEntries: ctxScopesEntries,
36 profilesEntries: ctxProfilesEntries,
37 needsSanitize: ctxNeedsSanitize,
38 } = _scopesFrom(data?.ctx?.profilesScopes);
39
40 const {
41 scopesEntries: sessionScopesEntries,
42 profilesEntries: sessionProfilesEntries,
43 needsSanitize: sessionNeedsSanitize,
44 } = _scopesFrom(data?.ctx?.session);
45
46 if (ctxNeedsSanitize || sessionNeedsSanitize) {
47 unclean = true;
48 }
49 if (unclean && sanitize) {
50 if (ctxNeedsSanitize) {
51 Object.assign(data.ctx.profilesScopes, _sanitizeProfilesScopes(ctxScopesEntries, ctxProfilesEntries));
52 }
53 if (sessionNeedsSanitize) {
54 Object.assign(data.ctx.session, _sanitizeProfilesScopes(sessionScopesEntries, sessionProfilesEntries));
55 }
56 }
57
58 return unclean;
59 }
60
61
62 /**
63 * Return any scope entries on an object, and whether sanitization is needed.
64 * @param {Object=} obj
65 * @returns {Object}
66 */
67 const _scopesFrom = (obj) => {
68 const scopesEntries = Object.entries(obj?.scopeIndex || {});
69 const profilesEntries = Object.entries(obj?.profileScopes || {});
70 const needsSanitize = scopesEntries.length || profilesEntries.length;
71 return {
72 scopesEntries,
73 profilesEntries,
74 needsSanitize,
75 };
76 };
77
78
79 /**
80 * @typedef {[String, Object]} ScopeEntry
81 */
82 /**
83 * Return new list of entries with scrubbed scopeDetails.
84 * @param {ScopeEntry[]} entries
85 * @returns {ScopeEntry[]}
86 */
87 const _scopeEntriesScrubber = (entries) => entries.map(([scopeName, scopeDetails]) => ([scopeName, { profiles: scopeDetails.profiles }]));
88
89
90 /**
91 * Create a new profilesScopes type object with scrubbed scope details.
92 * @param {ScopeEntry[]} scopesEntries
93 * @param {ScopeEntry[]} profilesEntries
94 * @returns {Object}
95 */
96 const _sanitizeProfilesScopes = (scopesEntries, profilesEntries) => {
97 const referencedScopesEntries = scopesEntries.filter(([_scopeName, scopeDetails]) => scopeDetails?.profiles?.length); // eslint-disable-line no-unused-vars
98 const scrubbedScopesEntries = _scopeEntriesScrubber(referencedScopesEntries);
99
100 const scrubbedProfilesEntries = profilesEntries.map(([profileName, profileScopes]) => {
101 const profileScopeEntries = Object.entries(profileScopes);
102 const scrubbedProfileScopeEntries = _scopeEntriesScrubber(profileScopeEntries);
103 const scrubbedProfileScopes = Object.fromEntries(scrubbedProfileScopeEntries);
104 return [profileName, scrubbedProfileScopes];
105 });
106
107 return {
108 scopeIndex: Object.fromEntries(scrubbedScopesEntries),
109 profileScopes: Object.fromEntries(scrubbedProfilesEntries),
110 };
111 };
112
113 module.exports = {
114 sanitizePostCredential,
115 reduceScopeVerbosity,
116 };