USTC x UCAS

USTC 统一身份认证登录界面改为 UCAS 样式

  1. // ==UserScript==
  2. // @name USTC x UCAS
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2.1
  5. // @description USTC 统一身份认证登录界面改为 UCAS 样式
  6. // @author PRO
  7. // @license gpl-3.0
  8. // @match https://passport.ustc.edu.cn/login*
  9. // @icon http://passport.ustc.edu.cn/images/favicon.ico
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15. let css = document.createElement("style");
  16. css.textContent = `
  17. body {
  18. background-image: url(https://icourse.ucas.ac.cn/static/img/c-3.8727b282.jpg);
  19. background-size: cover;
  20. }
  21. div.box.center {
  22. margin: 0px auto !important;
  23. border-radius: 6px;
  24. background: rgb(255, 255, 255);
  25. max-width: 400px;
  26. padding: 25px 25px 5px;
  27. box-shadow: none;
  28. height: unset;
  29. }
  30. div.card {
  31. padding: 0px;
  32. }
  33. form.form-style {
  34. margin: 0px;
  35. width: 100%;
  36. height: 282px;
  37. }
  38. #header > h3 {
  39. margin: 0 auto 30px auto;
  40. text-align: center;
  41. color: #707070;
  42. font-weight: 500;
  43. line-height: 1.1;
  44. }
  45. svg.prefix {
  46. position: absolute;
  47. left: 7px;
  48. top: 0;
  49. width: 14px;
  50. height: 39px;
  51. z-index: 1;
  52. color: #bcc6db;
  53. fill: currentColor;
  54. }
  55. input.input-box {
  56. height: 38px;
  57. position: relative;
  58. font-size: 14px;
  59. display: inline-block;
  60. width: 100%;
  61. padding-left: 30px;
  62. -webkit-appearance: none;
  63. background-color: #fff;
  64. background-image: none;
  65. border-radius: 4px;
  66. border: 1px solid #dcdfe6;
  67. -webkit-box-sizing: border-box;
  68. box-sizing: border-box;
  69. color: #606266;
  70. display: inline-block;
  71. font-size: inherit;
  72. outline: none;
  73. padding: 0px 15px 0px 30px;
  74. -webkit-transition: border-color .2s cubic-bezier(.645,.045,.355,1);
  75. transition: border-color .2s cubic-bezier(.645,.045,.355,1);
  76. }
  77. input.input-box:focus {
  78. border-color: #1890ff;
  79. }
  80. span.error-tip {
  81. color: #ff4949;
  82. font-size: 12px;
  83. line-height: 1;
  84. padding-top: 4px;
  85. position: absolute;
  86. top: 100%;
  87. left: 0;
  88. transition: transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);
  89. transform: scaleY(0);
  90. transform-origin: center top;
  91. }
  92. div.group {
  93. padding-top: 0px;
  94. padding-bottom: 0px;
  95. margin-bottom: 22px;
  96. height: unset;
  97. }
  98. div.validate {
  99. padding-top: 0px;
  100. padding-bottom: 0px;
  101. margin-bottom: 22px;
  102. height: 38px;
  103. }
  104. div.validate-img-area {
  105. width: 33%;
  106. height: 38px;
  107. }
  108. img.validate-img {
  109. margin-top: 0px;
  110. height: 38px;
  111. }
  112. div.bottom-box {
  113. height: 102px;
  114. }
  115. select.bottom-box-selector {
  116. bottom: unset;
  117. top: 0px;
  118. color: #606266;
  119. height: 19px;
  120. line-height: 20px;
  121. padding: 0px 0;
  122. font-size: 10px;
  123. margin: 0px 0px 25px;
  124. }
  125. a.bottom-box-button-area {
  126. color: #1890ff;
  127. float: right;
  128. position: unset;
  129. right: unset;
  130. bottom: unset;
  131. font-size: 14px;
  132. font-weight: 500;
  133. line-height: unset;
  134. }
  135. a.bottom-box-button-area:hover {
  136. color: #46a6ff;
  137. border-bottom: 1px solid #1890ff;
  138. }
  139. button.btn {
  140. width: 100%;
  141. padding: 10px 20px;
  142. font-size: 14px;
  143. border-radius: 4px;
  144. color: #fff;
  145. background-color: #1890ff;
  146. border: 1px solid #1890ff;
  147. font-weight: 400;
  148. line-height: 14px;
  149. letter-spacing: .2em;
  150. bottom: 22px;
  151. }
  152. button.btn:hover {
  153. background: #46a6ff;
  154. border-color: #46a6ff;
  155. }
  156. div#footer {
  157. position: fixed;
  158. bottom: 1em;
  159. color: #fff;
  160. font-family: Arial;
  161. font-size: 12px;
  162. letter-spacing: 1px;
  163. width: 100%;
  164. }
  165. div#footer a {
  166. color: #fff;
  167. }
  168. `;
  169.  
  170. let svg = document.createElement("svg");
  171. svg.style.display = "none";
  172. document.querySelector("body").insertAdjacentElement("afterbegin", svg);
  173. let input_mod = { // SVG from https://icourse.ucas.ac.cn/static/js/app.68f39dac.js
  174. "username": ["账号", "请输入您的账号", '<svg class="prefix" viewBox="0 0 130 130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797" /></svg>'],
  175. "password": ["密码", "请输入您的密码", '<svg class="prefix" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><defs><style type="text/css"></style></defs><path d="M868.593046 403.832442c-30.081109-28.844955-70.037123-44.753273-112.624057-44.753273L265.949606 359.079168c-42.554188 0-82.510202 15.908318-112.469538 44.690852-30.236652 28.782533-46.857191 67.222007-46.857191 108.198258l0 294.079782c0 40.977273 16.619516 79.414701 46.702672 108.136859 29.959336 28.844955 70.069869 44.814672 112.624057 44.814672l490.019383 0c42.585911 0 82.696444-15.969717 112.624057-44.814672 30.082132-28.844955 46.579875-67.222007 46.579875-108.136859L915.172921 511.968278C915.171897 471.053426 898.675178 432.677397 868.593046 403.832442zM841.821309 806.049083c0 22.098297-8.882298 42.772152-25.099654 58.306964-16.154935 15.661701-37.81935 24.203238-60.752666 24.203238L265.949606 888.559285c-22.934339 0-44.567032-8.54256-60.877509-24.264637-16.186657-15.474436-25.067932-36.148291-25.067932-58.246589L180.004165 511.968278c0-22.035876 8.881274-42.772152 25.192775-58.307987 16.186657-15.536858 37.81935-24.139793 60.753689-24.139793l490.019383 0c22.933315 0 44.597731 8.602935 60.752666 24.139793 16.21838 15.535835 25.099654 36.272112 25.099654 58.307987L841.822332 806.049083zM510.974136 135.440715c114.914216 0 208.318536 89.75214 208.318536 200.055338l73.350588 0c0-149.113109-126.366036-270.496667-281.669124-270.496667-155.333788 0-281.699824 121.383558-281.699824 270.496667l73.350588 0C302.623877 225.193879 396.059919 135.440715 510.974136 135.440715zM474.299865 747.244792l73.350588 0L547.650453 629.576859l-73.350588 0L474.299865 747.244792z" p-id="2751" /></svg>'],
  176. "validate": ["验证码", "请输入验证码", '<svg class="prefix" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" fill="#C6CCDA" p-id="1940" /><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" fill="#C6CCDA" p-id="1941" /></svg>']
  177. };
  178. for (let key in input_mod) {
  179. let input = document.querySelector("input#" + key);
  180. if (!input) continue;
  181. input.attributes.removeNamedItem("onfocus");
  182. input.attributes.removeNamedItem("onblur");
  183.  
  184. input.insertAdjacentHTML("afterend", input_mod[key][2]);
  185.  
  186. input.placeholder = input_mod[key][0];
  187.  
  188. let tip = document.createElement("span");
  189. tip.className = "error-tip";
  190. tip.textContent = input_mod[key][1];
  191. tip.id = key + "-error";
  192. input.parentNode.appendChild(tip);
  193.  
  194. let callback2 = (e) => {
  195. input.removeEventListener("blur", callback2);
  196. css.textContent += `
  197. input.input-box#${key}:invalid ~ span#${key}-error {
  198. visibility: unset;
  199. transform: scaleY(1);
  200. }
  201. input.input-box#${key}:invalid {
  202. border-color: #ff4949;
  203. }`;
  204. };
  205. let callback1 = (e) => {
  206. input.removeEventListener("click", callback1);
  207. input.addEventListener("blur", callback2);
  208. };
  209. input.addEventListener("click", callback1);
  210. }
  211. document.querySelector("head").appendChild(css);
  212.  
  213. let title = document.createElement("h3");
  214. title.textContent = "中科大在线系统";
  215. header.appendChild(title);
  216. let find_pwd = document.querySelector("a#findPassword");
  217. find_pwd.textContent = "找回用户名密码";
  218. let footer = document.querySelector("div#footer");
  219. document.querySelector("body").insertAdjacentElement("afterbegin", footer);
  220.  
  221. function cleanStyle(sel) {
  222. let ele = document.querySelector(sel);
  223. if (ele) ele.attributes.removeNamedItem("style");
  224. }
  225.  
  226. function tryRemove(sel) {
  227. let ele = document.querySelector(sel);
  228. if (ele) ele.remove();
  229. }
  230.  
  231. ["img.validate-img", "form.form-style", "select.bottom-box-selector"].forEach(cleanStyle);
  232. ["div.qrcode", "div.input_login", "div#header > h1.header-logo", "div#header > h1.header-des"].forEach(tryRemove);
  233.  
  234. document.querySelectorAll("span.bar").forEach((ele) => { ele.remove(); })
  235. })();