Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
166 lines
5.7 KiB
Plaintext
166 lines
5.7 KiB
Plaintext
'use strict';
|
|
|
|
var helper = require('./utils/helper.cjs');
|
|
var l33tTable = require('./data/l33tTable.cjs');
|
|
var translationKeys = require('./data/translationKeys.cjs');
|
|
var TrieNode = require('./matcher/dictionary/variants/matching/unmunger/TrieNode.cjs');
|
|
var l33tTableToTrieNode = require('./matcher/dictionary/variants/matching/unmunger/l33tTableToTrieNode.cjs');
|
|
var TimeEstimates = require('./TimeEstimates.cjs');
|
|
|
|
class Options {
|
|
constructor(options = {}, customMatchers = {}) {
|
|
this.matchers = {};
|
|
this.l33tTable = l33tTable;
|
|
this.trieNodeRoot = l33tTableToTrieNode(l33tTable, new TrieNode());
|
|
this.dictionary = {
|
|
userInputs: []
|
|
};
|
|
this.rankedDictionaries = {};
|
|
this.rankedDictionariesMaxWordSize = {};
|
|
this.translations = translationKeys;
|
|
this.graphs = {};
|
|
this.useLevenshteinDistance = false;
|
|
this.levenshteinThreshold = 2;
|
|
this.l33tMaxSubstitutions = 100;
|
|
this.maxLength = 256;
|
|
this.wordSequenceNames = ['cardinalNumbers', 'ordinalNumbers', 'daysOfWeek', 'months', 'seasons', 'timePeriods', 'rainbowColors', 'directions', 'intermediateDirections', 'sizeProgression', 'militaryAlphabet', 'planets', 'zodiacSigns', 'chineseZodiac'];
|
|
this.timeEstimationValues = {
|
|
scoring: {
|
|
...TimeEstimates.timeEstimationValuesDefaults.scoring
|
|
},
|
|
attackTime: {
|
|
...TimeEstimates.timeEstimationValuesDefaults.attackTime
|
|
}
|
|
};
|
|
this.setOptions(options);
|
|
Object.entries(customMatchers).forEach(([name, matcher]) => {
|
|
this.addMatcher(name, matcher);
|
|
});
|
|
}
|
|
isWordSequence(key) {
|
|
return this.wordSequenceNames.some(name => key === name || key.startsWith(`${name}-`));
|
|
}
|
|
// eslint-disable-next-line max-statements,complexity
|
|
setOptions(options = {}) {
|
|
if (options.l33tTable) {
|
|
this.l33tTable = options.l33tTable;
|
|
this.trieNodeRoot = l33tTableToTrieNode(options.l33tTable, new TrieNode());
|
|
}
|
|
if (options.dictionary) {
|
|
this.dictionary = options.dictionary;
|
|
this.setRankedDictionaries();
|
|
}
|
|
if (options.translations) {
|
|
this.setTranslations(options.translations);
|
|
}
|
|
if (options.graphs) {
|
|
this.graphs = options.graphs;
|
|
}
|
|
if (options.useLevenshteinDistance !== undefined) {
|
|
this.useLevenshteinDistance = options.useLevenshteinDistance;
|
|
}
|
|
if (options.levenshteinThreshold !== undefined) {
|
|
this.levenshteinThreshold = options.levenshteinThreshold;
|
|
}
|
|
if (options.l33tMaxSubstitutions !== undefined) {
|
|
this.l33tMaxSubstitutions = options.l33tMaxSubstitutions;
|
|
}
|
|
if (options.maxLength !== undefined) {
|
|
this.maxLength = options.maxLength;
|
|
}
|
|
if (options.timeEstimationValues !== undefined) {
|
|
TimeEstimates.checkTimeEstimationValues(options.timeEstimationValues);
|
|
this.timeEstimationValues = {
|
|
scoring: {
|
|
...options.timeEstimationValues.scoring
|
|
},
|
|
attackTime: {
|
|
...options.timeEstimationValues.attackTime
|
|
}
|
|
};
|
|
}
|
|
}
|
|
setTranslations(translations) {
|
|
if (this.checkCustomTranslations(translations)) {
|
|
this.translations = translations;
|
|
} else {
|
|
throw new Error('Invalid translations object fallback to keys');
|
|
}
|
|
}
|
|
checkCustomTranslations(translations) {
|
|
let valid = true;
|
|
Object.keys(translationKeys).forEach(type => {
|
|
if (type in translations) {
|
|
const translationType = type;
|
|
Object.keys(translationKeys[translationType]).forEach(key => {
|
|
if (!(key in translations[translationType])) {
|
|
valid = false;
|
|
}
|
|
const translation = translations[translationType][key];
|
|
if (typeof translation !== 'string' && typeof translation !== 'function') {
|
|
valid = false;
|
|
}
|
|
});
|
|
} else {
|
|
valid = false;
|
|
}
|
|
});
|
|
return valid;
|
|
}
|
|
setRankedDictionaries() {
|
|
const rankedDictionaries = {};
|
|
const rankedDictionariesMaxWorkSize = {};
|
|
Object.keys(this.dictionary).forEach(name => {
|
|
rankedDictionaries[name] = helper.buildRankedDictionary(this.dictionary[name]);
|
|
rankedDictionariesMaxWorkSize[name] = this.getRankedDictionariesMaxWordSize(this.dictionary[name]);
|
|
});
|
|
this.rankedDictionaries = rankedDictionaries;
|
|
this.rankedDictionariesMaxWordSize = rankedDictionariesMaxWorkSize;
|
|
}
|
|
getRankedDictionariesMaxWordSize(list) {
|
|
const data = list.map(el => {
|
|
if (typeof el !== 'string') {
|
|
return el.toString().length;
|
|
}
|
|
return el.length;
|
|
});
|
|
// do not use Math.max(...data) because it can result in max stack size error because every entry will be used as an argument
|
|
if (data.length === 0) {
|
|
return 0;
|
|
}
|
|
return data.reduce((a, b) => Math.max(a, b), -Infinity);
|
|
}
|
|
buildSanitizedRankedDictionary(list) {
|
|
const sanitizedInputs = [];
|
|
list.forEach(input => {
|
|
const inputType = typeof input;
|
|
if (inputType === 'string' || inputType === 'number' || inputType === 'boolean') {
|
|
sanitizedInputs.push(input.toString().toLowerCase());
|
|
}
|
|
});
|
|
return helper.buildRankedDictionary(sanitizedInputs);
|
|
}
|
|
getUserInputsOptions(dictionary) {
|
|
let rankedDictionary = {};
|
|
let rankedDictionaryMaxWordSize = 0;
|
|
if (dictionary) {
|
|
rankedDictionary = this.buildSanitizedRankedDictionary(dictionary);
|
|
rankedDictionaryMaxWordSize = this.getRankedDictionariesMaxWordSize(dictionary);
|
|
}
|
|
return {
|
|
rankedDictionary,
|
|
rankedDictionaryMaxWordSize
|
|
};
|
|
}
|
|
addMatcher(name, matcher) {
|
|
if (this.matchers[name]) {
|
|
console.info(`Matcher ${name} already exists`);
|
|
} else {
|
|
this.matchers[name] = matcher;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Options;
|
|
//# sourceMappingURL=Options.cjs.map
|