diff --git a/.vscode/settings.json b/.vscode/settings.json index 2b18b57..45464ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "cSpell.words": [ "bili", + "Geetest", "popconfirm" ] } \ No newline at end of file diff --git a/index.html b/index.html index 7d78507..70b424d 100644 --- a/index.html +++ b/index.html @@ -10,6 +10,7 @@ + diff --git a/public/js/gt.js b/public/js/gt.js new file mode 100644 index 0000000..a9d70d8 --- /dev/null +++ b/public/js/gt.js @@ -0,0 +1,353 @@ +"v0.4.8 Geetest Inc."; + +(function (window) { + "use strict"; + if (typeof window === 'undefined') { + throw new Error('Geetest requires browser environment'); + } + + var document = window.document; + var Math = window.Math; + var head = document.getElementsByTagName("head")[0]; + + function _Object(obj) { + this._obj = obj; + } + + _Object.prototype = { + _each: function (process) { + var _obj = this._obj; + for (var k in _obj) { + if (_obj.hasOwnProperty(k)) { + process(k, _obj[k]); + } + } + return this; + } + }; + + function Config(config) { + var self = this; + new _Object(config)._each(function (key, value) { + self[key] = value; + }); + } + + Config.prototype = { + api_server: 'api.geetest.com', + protocol: 'http://', + typePath: '/gettype.php', + fallback_config: { + slide: { + static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"], + type: 'slide', + slide: '/static/js/geetest.0.0.0.js' + }, + fullpage: { + static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"], + type: 'fullpage', + fullpage: '/static/js/fullpage.0.0.0.js' + } + }, + _get_fallback_config: function () { + var self = this; + if (isString(self.type)) { + return self.fallback_config[self.type]; + } else if (self.new_captcha) { + return self.fallback_config.fullpage; + } else { + return self.fallback_config.slide; + } + }, + _extend: function (obj) { + var self = this; + new _Object(obj)._each(function (key, value) { + self[key] = value; + }) + } + }; + var isNumber = function (value) { + return (typeof value === 'number'); + }; + var isString = function (value) { + return (typeof value === 'string'); + }; + var isBoolean = function (value) { + return (typeof value === 'boolean'); + }; + var isObject = function (value) { + return (typeof value === 'object' && value !== null); + }; + var isFunction = function (value) { + return (typeof value === 'function'); + }; + var MOBILE = /Mobi/i.test(navigator.userAgent); + var pt = MOBILE ? 3 : 0; + + var callbacks = {}; + var status = {}; + + var nowDate = function () { + var date = new Date(); + var year = date.getFullYear(); + var month = date.getMonth() + 1; + var day = date.getDate(); + var hours = date.getHours(); + var minutes = date.getMinutes(); + var seconds = date.getSeconds(); + + if (month >= 1 && month <= 9) { + month = '0' + month; + } + if (day >= 0 && day <= 9) { + day = '0' + day; + } + if (hours >= 0 && hours <= 9) { + hours = '0' + hours; + } + if (minutes >= 0 && minutes <= 9) { + minutes = '0' + minutes; + } + if (seconds >= 0 && seconds <= 9) { + seconds = '0' + seconds; + } + var currentdate = year + '-' + month + '-' + day + " " + hours + ":" + minutes + ":" + seconds; + return currentdate; + } + + var random = function () { + return parseInt(Math.random() * 10000) + (new Date()).valueOf(); + }; + + var loadScript = function (url, cb) { + var script = document.createElement("script"); + script.charset = "UTF-8"; + script.async = true; + + // 对geetest的静态资源添加 crossOrigin + if (/static\.geetest\.com/g.test(url)) { + script.crossOrigin = "anonymous"; + } + + script.onerror = function () { + cb(true); + }; + var loaded = false; + script.onload = script.onreadystatechange = function () { + if (!loaded && + (!script.readyState || + "loaded" === script.readyState || + "complete" === script.readyState)) { + + loaded = true; + setTimeout(function () { + cb(false); + }, 0); + } + }; + script.src = url; + head.appendChild(script); + }; + + var normalizeDomain = function (domain) { + // special domain: uems.sysu.edu.cn/jwxt/geetest/ + // return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn + return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest + }; + var normalizePath = function (path) { + path = path.replace(/\/+/g, '/'); + if (path.indexOf('/') !== 0) { + path = '/' + path; + } + return path; + }; + var normalizeQuery = function (query) { + if (!query) { + return ''; + } + var q = '?'; + new _Object(query)._each(function (key, value) { + if (isString(value) || isNumber(value) || isBoolean(value)) { + q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&'; + } + }); + if (q === '?') { + q = ''; + } + return q.replace(/&$/, ''); + }; + var makeURL = function (protocol, domain, path, query) { + domain = normalizeDomain(domain); + + var url = normalizePath(path) + normalizeQuery(query); + if (domain) { + url = protocol + domain + url; + } + + return url; + }; + + var load = function (config, send, protocol, domains, path, query, cb) { + var tryRequest = function (at) { + + var url = makeURL(protocol, domains[at], path, query); + loadScript(url, function (err) { + if (err) { + if (at >= domains.length - 1) { + cb(true); + // report gettype error + if (send) { + config.error_code = 508; + var url = protocol + domains[at] + path; + reportError(config, url); + } + } else { + tryRequest(at + 1); + } + } else { + cb(false); + } + }); + }; + tryRequest(0); + }; + + + var jsonp = function (domains, path, config, callback) { + if (isObject(config.getLib)) { + config._extend(config.getLib); + callback(config); + return; + } + if (config.offline) { + callback(config._get_fallback_config()); + return; + } + + var cb = "geetest_" + random(); + window[cb] = function (data) { + if (data.status == 'success') { + callback(data.data); + } else if (!data.status) { + callback(data); + } else { + callback(config._get_fallback_config()); + } + window[cb] = undefined; + try { + delete window[cb]; + } catch (e) { + } + }; + load(config, true, config.protocol, domains, path, { + gt: config.gt, + callback: cb + }, function (err) { + if (err) { + callback(config._get_fallback_config()); + } + }); + }; + + var reportError = function (config, url) { + load(config, false, config.protocol, ['monitor.geetest.com'], '/monitor/send', { + time: nowDate(), + captcha_id: config.gt, + challenge: config.challenge, + pt: pt, + exception_url: url, + error_code: config.error_code + }, function (err) { }) + } + + var throwError = function (errorType, config) { + var errors = { + networkError: '网络错误', + gtTypeError: 'gt字段不是字符串类型' + }; + if (typeof config.onError === 'function') { + config.onError(errors[errorType]); + } else { + throw new Error(errors[errorType]); + } + }; + + var detect = function () { + return window.Geetest || document.getElementById("gt_lib"); + }; + + if (detect()) { + status.slide = "loaded"; + } + + window.initGeetest = function (userConfig, callback) { + + var config = new Config(userConfig); + + if (userConfig.https) { + config.protocol = 'https://'; + } else if (!userConfig.protocol) { + config.protocol = window.location.protocol + '//'; + } + + // for KFC + if (userConfig.gt === '050cffef4ae57b5d5e529fea9540b0d1' || + userConfig.gt === '3bd38408ae4af923ed36e13819b14d42') { + config.apiserver = 'yumchina.geetest.com/'; // for old js + config.api_server = 'yumchina.geetest.com'; + } + + if (userConfig.gt) { + window.GeeGT = userConfig.gt + } + + if (userConfig.challenge) { + window.GeeChallenge = userConfig.challenge + } + + if (isObject(userConfig.getType)) { + config._extend(userConfig.getType); + } + jsonp([config.api_server || config.apiserver], config.typePath, config, function (newConfig) { + var type = newConfig.type; + var init = function () { + config._extend(newConfig); + callback(new window.Geetest(config)); + }; + + callbacks[type] = callbacks[type] || []; + var s = status[type] || 'init'; + if (s === 'init') { + status[type] = 'loading'; + + callbacks[type].push(init); + + load(config, true, config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) { + if (err) { + status[type] = 'fail'; + throwError('networkError', config); + } else { + status[type] = 'loaded'; + var cbs = callbacks[type]; + for (var i = 0, len = cbs.length; i < len; i = i + 1) { + var cb = cbs[i]; + if (isFunction(cb)) { + cb(); + } + } + callbacks[type] = []; + } + }); + } else if (s === "loaded") { + init(); + } else if (s === "fail") { + throwError('networkError', config); + } else if (s === "loading") { + callbacks[type].push(init); + } + }); + + }; + + +})(window); diff --git a/src/assets/global.less b/src/assets/global.less index 8afe361..1569ab7 100644 --- a/src/assets/global.less +++ b/src/assets/global.less @@ -17,7 +17,7 @@ body { .l-input { margin: 10px; padding: 10px 8px; - border: 2px solid #4b4b4b; + border: 2px solid #696969; border-radius: 0.5rem; transition: all 0.3s; @apply dark:bg-zinc-900; diff --git a/src/services/apis/vendor.ts b/src/services/apis/vendor.ts index c05b1e1..d4839d3 100644 --- a/src/services/apis/vendor.ts +++ b/src/services/apis/vendor.ts @@ -21,3 +21,18 @@ export const veriBiliBiliQRCode = useDefineApi< url: "/api/vendor/bilibili/login/qr", method: "POST" }); + +// 获取 哔哩哔哩 人机验证 +export const getBiliBiliCaptcha = useDefineApi< + { + headers: { Authorization: string }; + }, + { + token: string; + gt: string; + challenge: string; + } +>({ + url: "/api/vendor/bilibili/login/captcha", + method: "GET" +}); diff --git a/src/views/user/account.vue b/src/views/user/account.vue index f4aa085..5e1ed45 100644 --- a/src/views/user/account.vue +++ b/src/views/user/account.vue @@ -1,6 +1,6 @@