Password Generator

Generate random passwords with Context Menu

当前为 2023-06-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Password Generator
  3. // @name:tr Şifre Oluşturucu
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.1
  6. // @description Generate random passwords with Context Menu
  7. // @description:tr Sağ tık menüsünü kullanarak rastgele şifreler oluşturun
  8. // @author Muhammed Aktolu
  9. // @match *://*/*
  10. // @icon https://static-00.iconduck.com/assets.00/security-password-icon-1959x2048-sq0rdvok.png
  11. // @grant GM_registerMenuCommand
  12. // @grant GM_setValue
  13. // @grant GM_getValue
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. const generatePasswordForContextMenu = function(length = 16, minPerType = 2, uppercase = true, lowercase = true, number = true, symbol = false) {
  20. let string = '';
  21. let pass = {
  22. uppercase: true,
  23. lowercase: true,
  24. number: true,
  25. symbol: true,
  26. }
  27. let match;
  28. if (uppercase) {
  29. string += 'ABCDEFGHJKMNPQRSTUVWXYZ';
  30. }
  31.  
  32. if (lowercase) {
  33. string += 'abcdefghjkmnpqrstuvwxyz';
  34. }
  35.  
  36. if (number) {
  37. string += '23456789';
  38. }
  39.  
  40. if (symbol) {
  41. string += '!";#$%&\'()*+,-./:;<=>?@[]^_`{|}~';
  42. }
  43.  
  44. let password = Array.from(crypto.getRandomValues(new Uint32Array(length)))
  45. .map((x) => string[x % string.length])
  46. .join('');
  47.  
  48.  
  49.  
  50. if (uppercase) {
  51. match = password.match(/[A-Z]/g);
  52. if (!match || match.length < minPerType) {
  53. pass.uppercase = false;
  54. }
  55. }
  56.  
  57. if (lowercase) {
  58. match = password.match(/[a-z]/g);
  59. if (!match || match.length < minPerType) {
  60. pass.lowercase = false;
  61. }
  62. }
  63.  
  64. if (number) {
  65. match = password.match(/\d/g);
  66. if (!match || match.length < minPerType) {
  67. pass.number = false;
  68. }
  69. }
  70.  
  71. if (symbol) {
  72. match = password.match(/[^A-Za-z0-9]/g);
  73. if (!match || match.length < minPerType) {
  74. pass.symbol = false;
  75. }
  76. }
  77.  
  78. if (password.match(/(.)\1/) || !pass.uppercase || !pass.lowercase || !pass.number || !pass.symbol) {
  79. return generatePasswordForContextMenu(length, minPerType, uppercase, lowercase, number, symbol);
  80. } else {
  81. return password;
  82. }
  83. }
  84.  
  85. function multilineCssForContextMenu(css) {
  86. let el = document.createElement('style');
  87. el.appendChild(document.createTextNode(css));
  88. document.head.appendChild(el);
  89. return el;
  90. }
  91.  
  92. GM_registerMenuCommand('Generate Password', () => {
  93. //let length = GM_getValue('passwordGeneratorLength', '16');
  94. let password = generatePasswordForContextMenu(GM_getValue('pgLength', 16), GM_getValue('pgMinPerType', 2), GM_getValue('pgUppercase', true), GM_getValue('pgLowercase', true), GM_getValue('pgNumber', true), GM_getValue('pgSymbol', false));
  95.  
  96. // language=css
  97. let styleString = `
  98. .myTmBlock {
  99. position: fixed !important;
  100. width: 100vw !important;
  101. height: 100vh !important;
  102. z-index: 999999999 !important;
  103. display: flex !important;
  104. align-items: center !important;
  105. justify-content: center !important;
  106. background-color: rgba(0, 0, 0, .9) !important;
  107. left: 0 !important;
  108. top: 0 !important;
  109. }
  110. .myTmBlock * {
  111. font-family: Helvetica, Arial, sans-serif !important;
  112. line-height: 100% !important;
  113. color: whitesmoke !important;
  114. }
  115. .myTmBlock button {
  116. background-color: red !important;
  117. padding: 10px 30px !important;
  118. border: none !important;
  119. cursor: pointer !important;
  120. }
  121. .myTmBlock input {
  122. background-color: black !important;
  123. border: 1px solid whitesmoke !important;
  124. }
  125. .myTmBlock label {
  126. margin-right: 15px !important;
  127. cursor: pointer !important;
  128. -webkit-user-select: none !important;
  129. user-select: none !important;
  130. }
  131.  
  132. .myTmBox {
  133. text-align: center !important;
  134. }
  135.  
  136. #myTmPassword {
  137. font-size: 3rem !important;
  138. margin-bottom: 15px !important;
  139. }
  140. @media print {
  141. .myTmBlock {
  142. display: none !important;
  143. }
  144. }
  145. `;
  146.  
  147. let style = multilineCssForContextMenu(styleString);
  148. let block = document.createElement('div');
  149. block.classList.add('myTmBlock');
  150. document.body.appendChild(block);
  151.  
  152. // language=html
  153. block.innerHTML = `<div class="myTmBox">
  154. <div id="myTmPassword"></div>
  155. <div>
  156. <button id="myTmCopyPassword">Copy</button>
  157. <button id="myTmCancelPassword">Cancel</button>
  158. </div>
  159. <div style="margin-top: 100px">
  160. <div>
  161. Length: <input id="myTmPasswordLength" type="number" value="`+GM_getValue('pgLength', 16)+`" style="width: 60px; margin-right: 60px" min="8" max="64">
  162. Min Chars Per Type: <input id="myTmPasswordMinPerType" type="number" value="`+GM_getValue('pgMinPerType', 2)+`" style="width: 60px" min="0">
  163. </div>
  164. <div style="margin-top: 10px">
  165. <label>Uppercase:<input id="myTmUppercase" type="checkbox"`+(GM_getValue('pgUppercase', true) ? ' checked' : '')+`></label>
  166. <label>Lowercase:<input id="myTmLowercase" type="checkbox"`+(GM_getValue('pgLowercase', true) ? ' checked' : '')+`></label>
  167. <label>Number:<input id="myTmNumber" type="checkbox"`+(GM_getValue('pgNumber', true) ? ' checked' : '')+`></label>
  168. <label>Symbol:<input id="myTmSymbol" type="checkbox"`+(GM_getValue('pgSymbol', false) ? ' checked' : '')+`></label>
  169. </div>
  170. <button id="myTmReGeneratePassword" style="margin-top: 25px">Regenerate Password</button>
  171. </div>
  172. </div>`;
  173.  
  174. let passwordDiv = document.getElementById('myTmPassword');
  175. let copyButton = document.getElementById('myTmCopyPassword');
  176. let cancelButton = document.getElementById('myTmCancelPassword');
  177. let passwordLengthInput = document.getElementById('myTmPasswordLength');
  178. let minPerTypeInput = document.getElementById('myTmPasswordMinPerType');
  179. let uppercaseCheckBox = document.getElementById('myTmUppercase');
  180. let lowercaseCheckBox = document.getElementById('myTmLowercase');
  181. let numberCheckBox = document.getElementById('myTmNumber');
  182. let symbolCheckBox = document.getElementById('myTmSymbol');
  183. let reGenerateButton = document.getElementById('myTmReGeneratePassword');
  184. passwordDiv.innerText = password;
  185.  
  186. copyButton.addEventListener('click', () => {
  187. navigator.clipboard.writeText(password);
  188. block.remove();
  189. style.remove();
  190. });
  191.  
  192. cancelButton.addEventListener('click', () => {
  193. block.remove();
  194. style.remove();
  195. });
  196.  
  197. [passwordLengthInput, minPerTypeInput].forEach(item => {
  198. item.addEventListener('click', () => {
  199. item.select();
  200. });
  201. });
  202.  
  203. reGenerateButton.addEventListener('click', function() {
  204. GM_setValue('pgLength', parseInt(passwordLengthInput.value));
  205. GM_setValue('pgMinPerType', parseInt(minPerTypeInput.value));
  206. GM_setValue('pgUppercase', uppercaseCheckBox.checked);
  207. GM_setValue('pgLowercase', lowercaseCheckBox.checked);
  208. GM_setValue('pgNumber', numberCheckBox.checked);
  209. GM_setValue('pgSymbol', symbolCheckBox.checked);
  210. password = generatePasswordForContextMenu(parseInt(passwordLengthInput.value), parseInt(minPerTypeInput.value), uppercaseCheckBox.checked, lowercaseCheckBox.checked, numberCheckBox.checked, symbolCheckBox.checked);
  211. passwordDiv.innerText = password;
  212. });
  213. });
  214. })();