Password Generator

Generate random passwords with Context Menu

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

  1. // ==UserScript==
  2. // @name Password Generator
  3. // @name:tr Şifre Oluşturucu
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.2
  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. font-size: 15px !important;
  113. font-weight: 300 !important;
  114. letter-spacing: 0 !important;
  115. line-height: 100% !important;
  116. color: whitesmoke !important;
  117. float: none !important;
  118. border-radius: 0 !important;
  119. }
  120. .myTmBlock div {
  121. display: block !important;
  122. }
  123. .myTmBlock button {
  124. background-color: red !important;
  125. padding: 10px 30px !important;
  126. border: none !important;
  127. cursor: pointer !important;
  128. }
  129. .myTmBlock input {
  130. margin-inline: 0 !important;
  131. font-size: 13px !important;
  132. display: inline !important;
  133. }
  134. .myTmBlock input[type="number"] {
  135. background-color: black !important;
  136. border: 1px solid whitesmoke !important;
  137. width: 60px !important;
  138. padding: 1px 0 1px 2px !important;
  139. appearance: auto !important;
  140. }
  141. .myTmBlock label {
  142. margin-right: 15px !important;
  143. cursor: pointer !important;
  144. -webkit-user-select: none !important;
  145. user-select: none !important;
  146. }
  147.  
  148. .myTmBox {
  149. text-align: center !important;
  150. }
  151.  
  152. #myTmPassword {
  153. font-size: 3rem !important;
  154. margin-bottom: 15px !important;
  155. }
  156. `;
  157.  
  158. let style = multilineCssForContextMenu(styleString);
  159. let block = document.createElement('div');
  160. block.classList.add('myTmBlock');
  161. document.body.appendChild(block);
  162.  
  163. // language=html
  164. block.innerHTML = `<div class="myTmBox">
  165. <div id="myTmPassword"></div>
  166. <div>
  167. <button id="myTmCopyPassword">Copy</button>
  168. <button id="myTmCancelPassword">Cancel</button>
  169. </div>
  170. <div style="margin-top: 100px">
  171. <div>
  172. Length: <input id="myTmPasswordLength" type="number" value="`+GM_getValue('pgLength', 16)+`" style="margin-right: 60px" min="8" max="64">
  173. Min Chars Per Type: <input id="myTmPasswordMinPerType" type="number" value="`+GM_getValue('pgMinPerType', 2)+`" min="0">
  174. </div>
  175. <div style="margin-top: 10px">
  176. <label>Uppercase: <input id="myTmUppercase" type="checkbox"`+(GM_getValue('pgUppercase', true) ? ' checked' : '')+`></label>
  177. <label>Lowercase: <input id="myTmLowercase" type="checkbox"`+(GM_getValue('pgLowercase', true) ? ' checked' : '')+`></label>
  178. <label>Number: <input id="myTmNumber" type="checkbox"`+(GM_getValue('pgNumber', true) ? ' checked' : '')+`></label>
  179. <label>Symbol: <input id="myTmSymbol" type="checkbox"`+(GM_getValue('pgSymbol', false) ? ' checked' : '')+`></label>
  180. </div>
  181. <button id="myTmReGeneratePassword" style="margin-top: 25px">Regenerate Password</button>
  182. </div>
  183. </div>`;
  184.  
  185. let passwordDiv = document.getElementById('myTmPassword');
  186. let copyButton = document.getElementById('myTmCopyPassword');
  187. let cancelButton = document.getElementById('myTmCancelPassword');
  188. let passwordLengthInput = document.getElementById('myTmPasswordLength');
  189. let minPerTypeInput = document.getElementById('myTmPasswordMinPerType');
  190. let uppercaseCheckBox = document.getElementById('myTmUppercase');
  191. let lowercaseCheckBox = document.getElementById('myTmLowercase');
  192. let numberCheckBox = document.getElementById('myTmNumber');
  193. let symbolCheckBox = document.getElementById('myTmSymbol');
  194. let reGenerateButton = document.getElementById('myTmReGeneratePassword');
  195. passwordDiv.innerText = password;
  196.  
  197. copyButton.addEventListener('click', () => {
  198. navigator.clipboard.writeText(password);
  199. block.remove();
  200. style.remove();
  201. });
  202.  
  203. cancelButton.addEventListener('click', () => {
  204. block.remove();
  205. style.remove();
  206. });
  207.  
  208. [passwordLengthInput, minPerTypeInput].forEach(item => {
  209. item.addEventListener('click', () => {
  210. item.select();
  211. });
  212. });
  213.  
  214. reGenerateButton.addEventListener('click', function() {
  215. GM_setValue('pgLength', parseInt(passwordLengthInput.value));
  216. GM_setValue('pgMinPerType', parseInt(minPerTypeInput.value));
  217. GM_setValue('pgUppercase', uppercaseCheckBox.checked);
  218. GM_setValue('pgLowercase', lowercaseCheckBox.checked);
  219. GM_setValue('pgNumber', numberCheckBox.checked);
  220. GM_setValue('pgSymbol', symbolCheckBox.checked);
  221. password = generatePasswordForContextMenu(parseInt(passwordLengthInput.value), parseInt(minPerTypeInput.value), uppercaseCheckBox.checked, lowercaseCheckBox.checked, numberCheckBox.checked, symbolCheckBox.checked);
  222. passwordDiv.innerText = password;
  223. });
  224. });
  225. })();