diff --git a/docs/doc.fr.md b/docs/doc.fr.md index 3107ee8c3a24d28cda3fd8f343fed58ea6dae0eb..9f4f93715a3a9bd68e39b5dcc7abcbeb8c1b8fa5 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 49d8f70dae59e9a7c6c2dfc3c4cfda6eed127632..9822cb629e38a5af4ca787050e0f9991e1e0136c --- 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 733fc0e21a3fdcc393ef872245d73e87137d7e24..faa6ae25e21131d114bef832a4c81a7418ceb682 --- 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 bfd1fac0ad34dd45a37bc4c32bd3199fe8e49b9a..90705ca68b0ab9014a8967b0a34c4c7f8223d7f2 --- 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 cf55dd8bf5bb7168ee604ec2f2ef16c21c4edf75..97d63b57818e55d42ddcf52ac71c2060e058cd50 --- 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 0000000000000000000000000000000000000000..fc6e4d18c2bc48886aa15f3a550940d105f6010f --- /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 e33901386703037f12f076fb57226230bb81d0da..7760c609b28c2fb7d9a4bdce55b298055e062a82 --- 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 96bd259bff49a91fa5d20e6ed9460013e499f302..1bbd0a28e8caf47db254b7fd8c1b3e4c7d997b1c --- 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 eeb54176601a7998d3c332ce5ea6fce5342643a9..6c8376845e97819f547542724b7608522d73216e --- 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 abba0ba6e082ad71c6c56cf2afbc5a6cea0c171b..7e7eb0d4a36df2006767849e3e073737bfcac285 --- 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 0000000000000000000000000000000000000000..7f2179bd06d4a867e21cba8c630f0602e21876aa --- /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