From 1fb6508d1ee1e65f02d236cd038f1c237d1d1409 Mon Sep 17 00:00:00 2001 From: "[1000i100] Millicent Billette" <git@1000i100.fr> Date: Sat, 31 Dec 2022 03:34:01 +0100 Subject: [PATCH] v3.0.0-alpha4 TODO: - auto-save/resume - pub offline - doc / guide interactif --- docs/doc.fr.md | 62 +++++++++++++---- package-lock.json | 26 +++---- package.json | 2 +- src/js/logic/dico.mjs | 20 ++---- src/js/ux/2_inputSecrets.mjs | 51 +++++++++++--- src/js/ux/rangeOption.mjs | 85 +++++++++++++++++++++++ src/pages/steps/0_home.ejs | 4 +- src/pages/steps/2_inputSecrets.ejs | 28 +------- src/stylus/_var.styl | 1 + src/stylus/steps/page_2_inputSecrets.styl | 10 ++- src/stylus/widgets/rangeOption.styl | 21 ++++++ 11 files changed, 228 insertions(+), 82 deletions(-) mode change 100644 => 100755 package-lock.json mode change 100644 => 100755 package.json mode change 100644 => 100755 src/js/logic/dico.mjs mode change 100644 => 100755 src/js/ux/2_inputSecrets.mjs create mode 100644 src/js/ux/rangeOption.mjs mode change 100644 => 100755 src/pages/steps/0_home.ejs mode change 100644 => 100755 src/pages/steps/2_inputSecrets.ejs mode change 100644 => 100755 src/stylus/_var.styl mode change 100644 => 100755 src/stylus/steps/page_2_inputSecrets.styl create mode 100644 src/stylus/widgets/rangeOption.styl diff --git a/docs/doc.fr.md b/docs/doc.fr.md index 3107ee8..9f4f937 100644 --- a/docs/doc.fr.md +++ b/docs/doc.fr.md @@ -1,21 +1,14 @@ ## Guide d'utilisation -En bref : - -1. Indiquer la clef publique de votre compte (si vous ne la connaissez pas, chercher votre profil sur [cesium](https://cesium.ǧ1.money/#/app/wot/lg) via la fonction recherche de l'annuaire) -2. Indiquer les variantes d'identifiant secret que vous souhaitez tester. (Il est possible de générer plus de variantes automatiquement. [La documentation](#Documentation) ci dessous explique comment.) -3. Indiquer les variantes de mot de passe que vous souhaitez tester. -4. Cliquer sur le bouton `Gsper !` pour lancer la tentative de récupération des accès au compte. -5. Patienter jusqu'à l'apparition du message de fin de recherche (avec ou sans succès). - [Exemples d'utilisation pas à pas](exemples.fr.md) -## Documentation -Gsper met à votre disposition plusieurs boutons pour générer des variantes à tester à partir de celles que vous avez indiqué. -Voici comment les utiliser. - -### Bouton `MaJusculeS` +### Trouver votre clef publique + Indiquer la clef publique de votre compte (si vous ne la connaissez pas, chercher votre profil sur [cesium](https://cesium.ǧ1.money/#/app/wot/lg) via la fonction recherche de l'annuaire) +### Préparer la recherche de votre identifiant secret et mot de passe +#### La zone de saisie +#### Les options +##### Bouton `MaJusculeS` Génère des variantes des combinaisons à tester : - entièrement en majuscule - entièrement en minuscule @@ -33,7 +26,7 @@ MOT Mot moT ``` -### Bouton `désaccentué` +##### Bouton `désaccentué` Génère la variante désaccentué des combinaisons à tester. **Exemple :** @@ -45,6 +38,47 @@ sera remplacé par : Gavé de Ǧ1 Gave de G1 ``` +const regexDesc = { +'-1': 'Syntaxe > Auto : teste tel quel et après conversions syntaxique', +'0': `Syntaxe > Littérale : n'interprète aucun symbole, cherche tel quel`, +'1': `Syntaxe > Regex : interprète les symboles saisie pour générer les combinaisons correspondantes`, +'2': `Syntaxe > Mixte : teste tel quel et après conversions syntaxique`, +} +const mirrorDesc = { +'-1': 'Clone > Auto : teste les combinaisons miroir et les autres', +'0': `Clone > Oui : teste avec mot de passe dupliqué à l'identique comme identifiant secret)`, +'1': `Clone > Non : teste toute les combinaisons possible d'identifiant secret / mot de passe`, +} +const accentDesc = { +'-1': `Accents > Auto : génère les variantes testables en moins d'une heure`, +'0': `Accents > Inchangés : Laisse les accents tel quel`, +'1': `Accents > Avec et sans : Génère une variante sans aucun accent en plus de la version d'origine`, +'2': `Accents > Fluctuants : Pour chaque caractère accentué, essai avec et sans l'accent`, +} +const capsDesc = { +'-1': `Majuscules > Auto : génère les variantes testables en moins d'une heure`, +'0': `Majuscules > Inchangées : `, +'1': `Majuscules > Classiques : Tel queL, sans aucune, Première Lettre, TOUT`, +'2': `Majuscules > Fluctuantes : Pour chaque caractère en majuscule, essai avec et sans`, +} +#### L'explorateur de combinaison +#### L'aide intégrée +- Volet sécurité : Il contient les recommandations et bonnes pratiques pour utiliser Gsper sans risque (ou en réduisant les risques au maximum). +- Volet Aide : Il contient le guide d'utilisation que vous lisez actuellement. +#### La zone de lancement +En dessous des options se trouve deux informations clefs (nombre de combinaisons à tester et la durée estimée) ainsi que le bouton `Valider` pour lancer la recherche. + +NOTE: l'espace "Combinaisons à tester" peux contenir deux valeurs. La première est directement déduite de ce que vous avez listé comme secrets à tester pour retrouver votre compte. La seconde montre le nombre de combinaisons suplémentaires issue des heuristiques de Ǧsper avec les options que vous avez laissé en automatique. Ǧsper propose automatiquement d'essayer des variantes supplémentaires tant que le temps de les tester ne dépasse pas 1h. + +### Suivre l'avancement de la recherche + + +### L'écran de résultat + + +## Symboles et syntaxe utilisable pour approfondir vos recherches + + ### Bouton `<({[Avancé]})>` diff --git a/package-lock.json b/package-lock.json old mode 100644 new mode 100755 index 49d8f70..9822cb6 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "hasInstallScript": true, "dependencies": { - "g1lib": "^3.5.2" + "g1lib": "^3.5.5" }, "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", @@ -1004,9 +1004,9 @@ } }, "node_modules/g1lib": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.2.tgz", - "integrity": "sha512-T0gcaeKPtshRX4/anP/WMLSCVDjqcYq1dbpYje5nY3q5JCZuvWfl+U0ayCTS6uj3flu3VZbuFEKSztVI9zwu/Q==", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.5.tgz", + "integrity": "sha512-3JnCfMOc2ynTgCv4MsoeEAT9gGkwYMehFULOx6kMNY0tlPu1ytMI40UtcFPjCMUxnAXhBixtUTgbf8u1UxlgMA==", "funding": { "url": "https://git.duniter.org/libs/g1lib.js" } @@ -1606,9 +1606,9 @@ } }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -4456,9 +4456,9 @@ "dev": true }, "g1lib": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.2.tgz", - "integrity": "sha512-T0gcaeKPtshRX4/anP/WMLSCVDjqcYq1dbpYje5nY3q5JCZuvWfl+U0ayCTS6uj3flu3VZbuFEKSztVI9zwu/Q==" + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/g1lib/-/g1lib-3.5.5.tgz", + "integrity": "sha512-3JnCfMOc2ynTgCv4MsoeEAT9gGkwYMehFULOx6kMNY0tlPu1ytMI40UtcFPjCMUxnAXhBixtUTgbf8u1UxlgMA==" }, "get-caller-file": { "version": "2.0.5", @@ -4868,9 +4868,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true }, "kleur": { diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 733fc0e..faa6ae2 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "build:stylus": "stylus --include-css src/stylus/_all.styl -o generated/public/style.css" }, "dependencies": { - "g1lib": "^3.5.2" + "g1lib": "^3.5.5" }, "devDependencies": { "@fortawesome/fontawesome-free": "^5.15.2", diff --git a/src/js/logic/dico.mjs b/src/js/logic/dico.mjs old mode 100644 new mode 100755 index bfd1fac..90705ca --- a/src/js/logic/dico.mjs +++ b/src/js/logic/dico.mjs @@ -43,23 +43,15 @@ export function getStaticDico(){ window.getDico = getDico; window.getStaticDico = getStaticDico; export function getActualData(withSpeed = true) { - let miroir = parseInt(document.getElementById('optMiroir').value); - let accent = parseInt(document.getElementById('optAccent').value); - if(accent===-1) accent = undefined; - let lowerCase = parseInt(document.getElementById('optCaps').value); - if(lowerCase===-1) lowerCase = undefined; - let leetSpeak = parseInt(document.getElementById('optLeet').value); - if(leetSpeak===-1) leetSpeak = undefined; - let useCache = parseInt(document.getElementById('optCache').value); - if(useCache===-1) useCache = undefined; + const so = window.searchOptions; const result = { secrets: document.getElementById('secrets').value, options: { - idSecPwd:!miroir, - accent, - lowerCase, - leetSpeak, - 'cache':useCache, + escapeAll:so.regex.value<0?undefined:so.regex.value===0?1:so.regex.value===1?0:so.regex.value, + idSecPwd:so.mirror.value===0?0:1, + accent:so.accent.value<0?undefined:so.accent.value, + lowerCase:so.caps.value<0?undefined:so.caps.value, + leetSpeak:0, }, previewIndex: (window.browseIndex || 0), }; diff --git a/src/js/ux/2_inputSecrets.mjs b/src/js/ux/2_inputSecrets.mjs old mode 100644 new mode 100755 index cf55dd8..97d63b5 --- a/src/js/ux/2_inputSecrets.mjs +++ b/src/js/ux/2_inputSecrets.mjs @@ -3,16 +3,43 @@ import prettyMilliseconds from "pretty-ms"; import {timeUnitStrings} from "pretty-ms"; import {sendToWorker, subscribe} from "../logic/workerManager.mjs"; import {getActualData} from "../logic/dico.mjs"; +import RangeOption from "./rangeOption.mjs"; +const regexDesc = { + '-1': 'Syntaxe : auto-sélection', + '0': `Syntaxe : littérale`, + '1': `Syntaxe : regex`, + '2': `Syntaxe : combinée`, +} +const mirrorDesc = { + '-1': 'Clone : auto-sélection', + '0': `Clone : en miroir uniquement`, + '1': `Clone : toutes variantes possible`, +} +const accentDesc = { + '-1': `Accents : auto-sélection`, + '0': `Accents : inchangés`, + '1': `Accents : avec et sans`, + '2': `Accents : fluctuants`, +} +const capsDesc = { + '-1': `Majuscules : auto-sélection`, + '0': `Majuscules : inchangées`, + '1': `Majuscules : classiques`, + '2': `Majuscules : fluctuantes`, +} export function init() { const secretsInputNode = document.getElementById('secrets'); secretsInputNode.addEventListener('keyup', askPreview); secretsInputNode.addEventListener('change', askPreview); - document.getElementById('optMiroir').addEventListener('change', askPreview); - document.getElementById('optAccent').addEventListener('change', askPreview); - document.getElementById('optCaps').addEventListener('change', askPreview); - document.getElementById('optLeet').addEventListener('change', askPreview); - document.getElementById('optCache').addEventListener('change', askPreview); + + window.searchOptions = { + 'regex': new RangeOption('regex', -1, regexDesc, askPreview), + 'mirror': new RangeOption('mirror', -1, mirrorDesc, askPreview), + 'accent': new RangeOption('accent', -1, accentDesc, askPreview), + 'caps': new RangeOption('caps', -1, capsDesc, askPreview), + //TODO: AutoSave & resume + }; subscribe('fastPreview',updateFastPreviewDisplay); subscribe('smartPreview', updateSmartPreviewDisplay); subscribeToBenchResult(askPreview); @@ -58,11 +85,15 @@ function updateSmartPreviewDisplay(data){ document.getElementById('smartAltCount').innerHTML = smartVariantsExtraCount ? ` + ${smartVariantsExtraCount} auto suggestions` : ''; document.getElementById('initialTimeEstimate').innerHTML = `≈ ${timeFormat(smartDico.estimateDuration)}`; - document.getElementById('autoMiroir').value = smartDico.config.idSecPwd?0:1; - document.getElementById('autoAccent').value = smartDico.config.accent || 0; - document.getElementById('autoCaps').value = smartDico.config.lowerCase || 0; - document.getElementById('autoLeet').value = smartDico.config.leetSpeak || 0; - document.getElementById('autoCache').value = smartDico.config.cache?1:0; + + const sdc = smartDico.config; + const so = window.searchOptions; + so.regex.setComputed(sdc.escapeAll===1?0:sdc.escapeAll===0?1:sdc.escapeAll); + so.mirror.setComputed(sdc.idSecPwd?1:0); + so.accent.setComputed(sdc.accent || 0); + so.caps.setComputed(sdc.lowerCase || 0); + so.accent.setComputed(sdc.accent || 0); + try{window.displayBrowsePreview();}catch (e){} } diff --git a/src/js/ux/rangeOption.mjs b/src/js/ux/rangeOption.mjs new file mode 100644 index 0000000..fc6e4d1 --- /dev/null +++ b/src/js/ux/rangeOption.mjs @@ -0,0 +1,85 @@ + +const hostNode = document.getElementById('optionsWidgetList'); +export default function RangeOption(fieldId, initialValue, descArray, uiListener){ + const self = {}; + self.listeners={}; + + const grpNode = document.createElement('fieldset'); + grpNode.id = `roGrp_${fieldId}`; + grpNode.classList.add('rangeOptionGrp'); + + const descLabel = document.createElement('label'); + descLabel.classList.add('dynDesc'); + descLabel.innerHTML = descArray[initialValue]; + grpNode.appendChild(descLabel); + + const hiddenNode = document.createElement('input'); + hiddenNode.setAttribute('type','hidden'); + hiddenNode.id = `ro_${fieldId}`; + hiddenNode.value = initialValue; + grpNode.appendChild(hiddenNode); + + const checkBoxNode = document.createElement('input'); + checkBoxNode.setAttribute('type','checkbox'); + checkBoxNode.id = `roSwitchAuto_${fieldId}`; + checkBoxNode.classList.add('roSwitchAuto'); + checkBoxNode.value = '-1'; + grpNode.appendChild(checkBoxNode); + + const labelForAuto = document.createElement('label'); + labelForAuto.setAttribute('for',`roSwitchAuto_${fieldId}`); + labelForAuto.classList.add('autoSwitchDesc'); + labelForAuto.innerHTML = 'auto'; + grpNode.appendChild(labelForAuto); + + const rangeNode = document.createElement('input'); + rangeNode.setAttribute('type','range'); + rangeNode.id = `roManualRangeInput_${fieldId}`; + rangeNode.classList.add('roManualRangeInput'); + rangeNode.setAttribute('min','0'); + rangeNode.setAttribute('max',`${Object.keys(descArray).reduce((acc,cur) => Math.max(parseInt(cur),acc),0)}`); + rangeNode.setAttribute('step','1'); + rangeNode.value = initialValue; + grpNode.appendChild(rangeNode); + + const viewNode = document.createElement('input'); + viewNode.setAttribute('type','range'); + viewNode.id = `roAutoRangeView_${fieldId}`; + viewNode.classList.add('roAutoRangeView'); + viewNode.setAttribute('min','0'); + viewNode.setAttribute('max',`${Object.keys(descArray).reduce((acc,cur) => Math.max(parseInt(cur),acc),0)}`); + viewNode.setAttribute('step','1'); + viewNode.setAttribute('disabled','disabled'); + viewNode.value = `${Math.max(0, initialValue)}`; + grpNode.appendChild(viewNode); + + hostNode.appendChild(grpNode); + + self.listen = (listenerName,callbackFunction)=>self.listeners[listenerName] = callbackFunction; + self.setComputed = val=>{ + viewNode.value = val; + descLabel.innerHTML = descArray[val]; + } + self.setUserChoice = val=>{ + val = parseInt(val); + hiddenNode.value = val; + self.value = val; + descLabel.innerHTML = descArray[val]; + if(val<0) checkBoxNode.checked = true; + else { + checkBoxNode.checked = false; + rangeNode.value = val; + } + } + function uiChanged(){ + const mode = parseInt(hiddenNode.value); + self.value = mode; + descLabel.innerHTML = descArray[mode]; + Object.keys(self.listeners).forEach(k=>self.listeners[k](mode)); + } + checkBoxNode.addEventListener('change', ()=>uiChanged(hiddenNode.value = checkBoxNode.checked?-1:(rangeNode.value || 0))); + rangeNode.addEventListener('change', ()=>uiChanged(hiddenNode.value = rangeNode.value)); + if(typeof uiListener !== 'undefined') self.listen('default',uiListener) + if(initialValue) self.setUserChoice(initialValue); + return self; +} diff --git a/src/pages/steps/0_home.ejs b/src/pages/steps/0_home.ejs old mode 100644 new mode 100755 index e339013..7760c60 --- a/src/pages/steps/0_home.ejs +++ b/src/pages/steps/0_home.ejs @@ -5,10 +5,10 @@ et vous indique s'il y a correspondance avec la clef publique de votre compte. Il peut aussi générer des variantes à partir de ce que vous lui indiquez. Cela vous donne plus de chances de trouver la bonne combinaison. -Si la bonne combinaison n'est pas parmi ce qu'il test, Ǧsper ne pourra pas retrouver l'accès à votre compte. +Si la bonne combinaison n'est pas parmi ce qu'il teste, Ǧsper ne pourra pas retrouver l'accès à votre compte. Tester un grand nombre de combinaisons peut prendre des années. -Ǧsper vous fourni un estimatif pour vous aider à cibler vos essais pour rester dans un délais raisonnable. +Ǧsper vous fourni un estimatif pour vous aider à cibler vos essais pour rester dans un délai raisonnable. En sécurité informatique, ce que des outils tel que Ǧsper font est appelé <a href="https://fr.wikipedia.org/wiki/Attaque_par_dictionnaire" target="_blank">attaque par dictionnaire.</a> diff --git a/src/pages/steps/2_inputSecrets.ejs b/src/pages/steps/2_inputSecrets.ejs old mode 100644 new mode 100755 index 96bd259..1bbd0a2 --- a/src/pages/steps/2_inputSecrets.ejs +++ b/src/pages/steps/2_inputSecrets.ejs @@ -5,34 +5,8 @@ <div id="test_area"> <div class="status"> - <fieldset> + <fieldset id="optionsWidgetList"> <legend>Options</legend> - - - <label>Miroir</label> - <input id="optMiroir" type="range" min="0" max="1" step="1" value="0"/> - <input id="autoMiroir" type="range" min="0" max="1" step="1" value="0" disabled/> - - <label>Désaccentué</label> - <input id="optAccent" type="range" min="-1" max="2" step="1" value="-1"/> - <input id="autoAccent" type="range" min="-1" max="2" step="1" value="-1" disabled/> - - <label>Sans majuscule</label> - <input id="optCaps" type="range" min="-1" max="4" step="1" value="-1"/> - <input id="autoCaps" type="range" min="-1" max="4" step="1" value="-1" disabled/> - - <label>LeetSpeak</label> - <input id="optLeet" type="range" min="-1" max="3" step="1" value="-1"/> - <input id="autoLeet" type="range" min="-1" max="3" step="1" value="-1" disabled/> - - <label>Cache</label> - <input id="optCache" type="range" min="-1" max="1" step="1" value="-1"/> - <input id="autoCache" type="range" min="-1" max="1" step="1" value="-1" disabled/> - - <!--<label>AutoSave & resume</label> - <input id="optSave" type="range" min="-1" max="1" step="1" value="-1"/> - <input id="autoSave" type="range" min="-1" max="1" step="1" value="-1" disabled/> - --> </fieldset> <p>Combinaisons à tester:</p> <div><span id="directAltCount">?</span><span id="smartAltCount"></span></div> diff --git a/src/stylus/_var.styl b/src/stylus/_var.styl old mode 100644 new mode 100755 index eeb5417..6c83768 --- a/src/stylus/_var.styl +++ b/src/stylus/_var.styl @@ -1,5 +1,6 @@ primaryColor = #45425A secondaryColor = #D0D5DF secondaryColorBis = #B2B4C2 +secondaryColorTer = #a6acce thirdColor = #95B46A fourthColor = #FFB140 diff --git a/src/stylus/steps/page_2_inputSecrets.styl b/src/stylus/steps/page_2_inputSecrets.styl old mode 100644 new mode 100755 index abba0ba..7e7eb0d --- a/src/stylus/steps/page_2_inputSecrets.styl +++ b/src/stylus/steps/page_2_inputSecrets.styl @@ -87,4 +87,12 @@ list-style: circle - +// ----------- + +#optionsWidgetList + border none + border-bottom 1px solid secondaryColor + > legend + font-weight bold + margin-bottom 20px + font-size 120% diff --git a/src/stylus/widgets/rangeOption.styl b/src/stylus/widgets/rangeOption.styl new file mode 100644 index 0000000..7f2179b --- /dev/null +++ b/src/stylus/widgets/rangeOption.styl @@ -0,0 +1,21 @@ +.rangeOptionGrp + border none + margin-bottom 20px + * + height 14px + .dynDesc + display block + height auto + text-align left; + .autoSwitchDesc + display inline-block + padding 0 5px + .roSwitchAuto:checked ~ .roManualRangeInput + display none + input[type="range"] + width calc(100% - 90px) + .roSwitchAuto:not(:checked) + ~ .roAutoRangeView + display none + ~ .autoSwitchDesc + text-decoration line-through 2px -- GitLab