Password Generator

Generate random passwords with Context Menu

目前为 2023-06-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Password Generator
  3. // @name:tr Şifre Oluşturucu
  4. // @namespace https://aktolu.com/
  5. // @version 0.5
  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. // @noframes
  12. // @grant GM_addElement
  13. // @grant GM_addStyle
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_setValue
  16. // @grant GM_getValue
  17. // @grant GM_setClipboard
  18. // ==/UserScript==
  19.  
  20. /* jshint esversion: 11 */
  21.  
  22. (function() {
  23. 'use strict';
  24. // Start Global
  25. const toast = function(text, type = 'success') {
  26. document.getElementById('myToast')?.remove();
  27. document.getElementById('myToastStyle')?.remove();
  28. // language=css
  29. let styleString = `
  30. #myToast {
  31. display: inline-block !important;
  32. padding: 20px !important;
  33. opacity: .6 !important;
  34. color: white !important;
  35. background-color: black !important;
  36. position: fixed !important;
  37. top: 20px !important;
  38. right: 20px !important;
  39. z-index: 9999999999999999999999 !important;
  40. }
  41. #myToast.success {
  42. background-color: green !important;
  43. }
  44. #myToast.warning {
  45. background-color: orange !important;
  46. }
  47. #myToast.danger {
  48. background-color: darkred !important;
  49. }
  50. `;
  51. let style = multilineCss(styleString, 'myToastStyle');
  52. let block = GM_addElement(document.body, 'div', {
  53. id: 'myToast',
  54. class: type,
  55. });
  56. block.innerText = text;
  57. setTimeout(() => {
  58. block.remove();
  59. style.remove();
  60. }, 5000);
  61. }
  62. const multilineCss = function(style, id = '') {
  63. let el = GM_addStyle(style);
  64. if (id !== '') {
  65. el.id = id;
  66. }
  67. return el;
  68. }
  69. // End Global
  70. // Start Password Generator
  71. const generatePassword = function(length = 16, minPerType = 2, uppercase = true, lowercase = true, number = true, symbol = false) {
  72. let string = '';
  73. let pass = {
  74. uppercase: true,
  75. lowercase: true,
  76. number: true,
  77. symbol: true,
  78. }
  79. let match;
  80. if (uppercase) {
  81. string += 'ABCDEFGHJKMNPQRSTUVWXYZ';
  82. }
  83. if (lowercase) {
  84. string += 'abcdefghjkmnpqrstuvwxyz';
  85. }
  86. if (number) {
  87. string += '23456789';
  88. }
  89. if (symbol) {
  90. string += '!";#$%&\'()*+,-./:;<=>?@[]^_`{|}~';
  91. }
  92. let password = Array.from(crypto.getRandomValues(new Uint32Array(length)))
  93. .map((x) => string[x % string.length])
  94. .join('');
  95. if (uppercase) {
  96. match = password.match(/[A-Z]/g);
  97. if (!match || match.length < minPerType) {
  98. pass.uppercase = false;
  99. }
  100. }
  101. if (lowercase) {
  102. match = password.match(/[a-z]/g);
  103. if (!match || match.length < minPerType) {
  104. pass.lowercase = false;
  105. }
  106. }
  107. if (number) {
  108. match = password.match(/\d/g);
  109. if (!match || match.length < minPerType) {
  110. pass.number = false;
  111. }
  112. }
  113. if (symbol) {
  114. match = password.match(/[^A-Za-z0-9]/g);
  115. if (!match || match.length < minPerType) {
  116. pass.symbol = false;
  117. }
  118. }
  119. if (password.match(/(.)\1/) || !pass.uppercase || !pass.lowercase || !pass.number || !pass.symbol) {
  120. return generatePassword(length, minPerType, uppercase, lowercase, number, symbol);
  121. } else {
  122. return password;
  123. }
  124. }
  125. // End Password Generator
  126. GM_registerMenuCommand('Generate Password', function() {
  127. if (document.getElementById('pgBlock')) {
  128. return false;
  129. }
  130. //let length = GM_getValue('passwordGeneratorLength', '16');
  131. let password = generatePassword(GM_getValue('pgLength', 16), GM_getValue('pgMinPerType', 2), GM_getValue('pgUppercase', true), GM_getValue('pgLowercase', true), GM_getValue('pgNumber', true), GM_getValue('pgSymbol', false));
  132. // language=css
  133. let styleString = `
  134. #pgBlock {
  135. position: fixed !important;
  136. width: 100vw !important;
  137. height: 100vh !important;
  138. z-index: 999999999999999999999 !important;
  139. display: flex !important;
  140. align-items: center !important;
  141. justify-content: center !important;
  142. background-color: rgba(0, 0, 0, .9) !important;
  143. left: 0 !important;
  144. top: 0 !important;
  145. }
  146. #pgBlock * {
  147. font-family: Helvetica, Arial, sans-serif !important;
  148. font-size: 15px !important;
  149. font-weight: 300 !important;
  150. letter-spacing: 0 !important;
  151. line-height: 100% !important;
  152. color: whitesmoke !important;
  153. float: none !important;
  154. border-radius: 0 !important;
  155. }
  156. #pgBlock div {
  157. display: block !important;
  158. }
  159. #pgBlock button {
  160. background-color: red !important;
  161. padding: 10px 30px !important;
  162. border: none !important;
  163. cursor: pointer !important;
  164. }
  165. #pgBlock input {
  166. margin-inline: 0 !important;
  167. font-size: 13px !important;
  168. display: inline !important;
  169. }
  170. #pgBlock input[type="number"] {
  171. background-color: black !important;
  172. border: 1px solid whitesmoke !important;
  173. width: 60px !important;
  174. padding: 1px 0 1px 2px !important;
  175. appearance: auto !important;
  176. }
  177. #pgBlock label {
  178. margin-right: 15px !important;
  179. cursor: pointer !important;
  180. -webkit-user-select: none !important;
  181. user-select: none !important;
  182. }
  183.  
  184. .pgBox {
  185. text-align: center !important;
  186. }
  187.  
  188. #pgPassword {
  189. font-size: 3rem !important;
  190. margin-bottom: 15px !important;
  191. }
  192. `;
  193. let style = multilineCss(styleString);
  194. let block = GM_addElement(document.body, 'div', {
  195. id: 'pgBlock',
  196. });
  197. // language=html
  198. block.innerHTML = `<div class="pgBox">
  199. <div id="pgPassword"></div>
  200. <div>
  201. <button id="pgCopyPassword">Copy</button>
  202. <button id="pgCancelPassword">Cancel</button>
  203. </div>
  204. <div style="margin-top: 100px">
  205. <div>
  206. Length: <input id="pgPasswordLength" type="number" value="`+GM_getValue('pgLength', 16)+`" style="margin-right: 60px" min="8" max="64">
  207. Min Chars Per Type: <input id="pgPasswordMinPerType" type="number" value="`+GM_getValue('pgMinPerType', 2)+`" min="0">
  208. </div>
  209. <div style="margin-top: 10px">
  210. <label>Uppercase: <input id="pgUppercase" type="checkbox"`+(GM_getValue('pgUppercase', true) ? ' checked' : '')+`></label>
  211. <label>Lowercase: <input id="pgLowercase" type="checkbox"`+(GM_getValue('pgLowercase', true) ? ' checked' : '')+`></label>
  212. <label>Number: <input id="pgNumber" type="checkbox"`+(GM_getValue('pgNumber', true) ? ' checked' : '')+`></label>
  213. <label>Symbol: <input id="pgSymbol" type="checkbox"`+(GM_getValue('pgSymbol', false) ? ' checked' : '')+`></label>
  214. </div>
  215. <button id="pgReGeneratePassword" style="margin-top: 25px">Regenerate Password</button>
  216. </div>
  217. </div>`;
  218. let passwordDiv = document.getElementById('pgPassword');
  219. let copyButton = document.getElementById('pgCopyPassword');
  220. let cancelButton = document.getElementById('pgCancelPassword');
  221. let passwordLengthInput = document.getElementById('pgPasswordLength');
  222. let minPerTypeInput = document.getElementById('pgPasswordMinPerType');
  223. let uppercaseCheckBox = document.getElementById('pgUppercase');
  224. let lowercaseCheckBox = document.getElementById('pgLowercase');
  225. let numberCheckBox = document.getElementById('pgNumber');
  226. let symbolCheckBox = document.getElementById('pgSymbol');
  227. let reGenerateButton = document.getElementById('pgReGeneratePassword');
  228. passwordDiv.innerText = password;
  229. copyButton.addEventListener('click', () => {
  230. navigator.clipboard.writeText(password)
  231. .then(r => toast('Password has been copied successfully.'));
  232. block.remove();
  233. style.remove();
  234. });
  235. cancelButton.addEventListener('click', () => {
  236. block.remove();
  237. style.remove();
  238. });
  239. [passwordLengthInput, minPerTypeInput].forEach(item => {
  240. item.addEventListener('click', () => {
  241. item.select();
  242. });
  243. });
  244. reGenerateButton.addEventListener('click', function() {
  245. GM_setValue('pgLength', parseInt(passwordLengthInput.value));
  246. GM_setValue('pgMinPerType', parseInt(minPerTypeInput.value));
  247. GM_setValue('pgUppercase', uppercaseCheckBox.checked);
  248. GM_setValue('pgLowercase', lowercaseCheckBox.checked);
  249. GM_setValue('pgNumber', numberCheckBox.checked);
  250. GM_setValue('pgSymbol', symbolCheckBox.checked);
  251. password = generatePassword(parseInt(passwordLengthInput.value), parseInt(minPerTypeInput.value), uppercaseCheckBox.checked, lowercaseCheckBox.checked, numberCheckBox.checked, symbolCheckBox.checked);
  252. passwordDiv.innerText = password;
  253. });
  254. });
  255. })();