UNPKG

@gdjiami/jslib

Version:

Jiami FrontEnd helpers and Services

403 lines (322 loc) 10.2 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; /** * 通用的Token鉴权机制服务 */ import { getSearch } from './http'; import { EventEmitter } from './EventEmitter'; export var SMS_CLIENT_TYPE = ['qxSMS', 'qxEEMS', 'qxEMS', 'qxCMS']; export var TOKEN_HEADER = 'X-Access-Token'; /** * 鉴权类型 */ export var GRANT_TYPE; (function (GRANT_TYPE) { GRANT_TYPE["Auth"] = "authorization_code"; GRANT_TYPE["Refresh"] = "refresh_token"; })(GRANT_TYPE || (GRANT_TYPE = {})); var TOKEN_CACHE_KEY = '__auth__'; var REFRESH_DURATION = 10 * 1000; /** * 基于Token的鉴权服务 * ## events * info-updated */ export var TokenAuthService = /*#__PURE__*/ function (_EventEmitter) { _inheritsLoose(TokenAuthService, _EventEmitter); function TokenAuthService(config) { var _this; _this = _EventEmitter.call(this) || this; _this.refreshCallbacks = []; _this.config = config; _this.getUserInfo(); return _this; } var _proto = TokenAuthService.prototype; _proto.logout = function logout() { this.clean(); }; _proto.clean = function clean() { // @ts-ignore this.info = undefined; this.storage.removeItem(TOKEN_CACHE_KEY); } /** * 更新鉴权信息 */ ; _proto.saveAuthInfo = function saveAuthInfo(info) { this.info = info; this.storage.setItem(TOKEN_CACHE_KEY, JSON.stringify(info)); this.infoUpdated(); } /** * 通过用户名密码鉴权 */ ; _proto.authByPassword = function authByPassword(params) { var info, res; return _regeneratorRuntime.async(function authByPassword$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!(this.config.getTokenByPassword == null)) { _context.next = 2; break; } throw new Error('TokenAuthService: getTokenByPassword 未实现'); case 2: info = this.storage.getItem(TOKEN_CACHE_KEY); if (!(info != null)) { _context.next = 7; break; } this.info = JSON.parse(info); if (this.config.onAuthSuccess) { this.config.onAuthSuccess(this.info); } return _context.abrupt("return"); case 7: _context.prev = 7; _context.next = 10; return _regeneratorRuntime.awrap(this.config.getTokenByPassword(params)); case 10: res = _context.sent; this.saveAuthInfo(res); this.handleAuthSuccess(); _context.next = 19; break; case 15: _context.prev = 15; _context.t0 = _context["catch"](7); if (this.config.onAuthFailed) { this.config.onAuthFailed(_context.t0); } throw _context.t0; case 19: case "end": return _context.stop(); } } }, null, this, [[7, 15]]); } /** * token 鉴权 */ ; _proto.auth = function auth(overrideParams) { var info, params, payload, res; return _regeneratorRuntime.async(function auth$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (!(this.config.getToken == null)) { _context2.next = 2; break; } throw new Error('TokenAuthService: getToken 未实现'); case 2: info = this.storage.getItem(TOKEN_CACHE_KEY); if (!(info != null)) { _context2.next = 7; break; } this.info = JSON.parse(info); if (this.config.onAuthSuccess) { this.config.onAuthSuccess(this.info); } return _context2.abrupt("return"); case 7: _context2.prev = 7; params = getSearch(window.location.search); if (!('from' in params)) { _context2.next = 15; break; } if (!(params.accessToken == null)) { _context2.next = 12; break; } throw new Error("\u9274\u6743\u5931\u8D25(from=" + params.from + ")\uFF0CaccessToken\u4E3Anull"); case 12: this.saveAuthInfo(params); this.handleAuthSuccess(); return _context2.abrupt("return"); case 15: if (!(params.code == null)) { _context2.next = 17; break; } throw new Error('鉴权失败,code为null'); case 17: payload = _extends({ code: params.code, corpId: params.corp_id || '', clientId: this.config.clientId, grantType: GRANT_TYPE.Auth }, overrideParams || {}); _context2.next = 20; return _regeneratorRuntime.awrap(this.config.getToken(payload)); case 20: res = _context2.sent; this.saveAuthInfo(res); this.handleAuthSuccess(); _context2.next = 29; break; case 25: _context2.prev = 25; _context2.t0 = _context2["catch"](7); if (this.config.onAuthFailed) { this.config.onAuthFailed(_context2.t0); } throw _context2.t0; case 29: case "end": return _context2.stop(); } } }, null, this, [[7, 25]]); } /** * 刷新token * 这个方法可能会被调用多次,所以要将它们加入队列,以便后续重试 */ ; _proto.refresh = function refresh() { var resRef, rejRef, promise, params, res, now, list, _list; return _regeneratorRuntime.async(function refresh$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: if (!(this.info == null)) { _context3.next = 2; break; } throw new Error('必须在鉴权之后才能刷新Token'); case 2: if (!this.refreshing) { _context3.next = 8; break; } promise = new Promise(function (res, rej) { resRef = res; rejRef = rej; }); this.refreshCallbacks.push(function (err) { return err != null ? rejRef(err) : resRef(); }); _context3.next = 7; return _regeneratorRuntime.awrap(promise); case 7: return _context3.abrupt("return"); case 8: _context3.prev = 8; params = { refreshToken: this.info.refreshToken, grantType: GRANT_TYPE.Refresh }; _context3.next = 12; return _regeneratorRuntime.awrap(this.config.refreshToken(params)); case 12: res = _context3.sent; now = Date.now(); if (!(this.lastRefreshTime != null && now - this.lastRefreshTime < REFRESH_DURATION)) { _context3.next = 16; break; } throw new Error(this.config.refreshErrorMessage || '会话失效'); case 16: this.lastRefreshTime = now; this.saveAuthInfo(_extends({}, this.info, {}, res)); if (this.refreshCallbacks.length) { list = this.refreshCallbacks; this.refreshCallbacks = []; list.forEach(function (i) { return i(); }); } _context3.next = 27; break; case 21: _context3.prev = 21; _context3.t0 = _context3["catch"](8); if (this.refreshCallbacks.length) { _list = this.refreshCallbacks; this.refreshCallbacks = []; _list.forEach(function (i) { return i(_context3.t0); }); } if (this.config.onRefreshFailed) { this.config.onRefreshFailed(_context3.t0); } // 清理鉴权信息 this.clean(); throw _context3.t0; case 27: _context3.prev = 27; this.refreshing = false; return _context3.finish(27); case 30: case "end": return _context3.stop(); } } }, null, this, [[8, 21, 27, 30]]); }; _proto.isAdmin = function isAdmin() { return SMS_CLIENT_TYPE.indexOf(this.info.clientType) !== -1; } /** * 获取token */ ; _proto.getToken = function getToken() { return this.info && this.info.accessToken; } /** * 获取用户信息 */ ; _proto.getUserInfo = function getUserInfo() { if (this.info) { return this.info; } var info = this.storage.getItem(TOKEN_CACHE_KEY); if (info != null) { this.info = JSON.parse(info); } return this.info; }; _proto.infoUpdated = function infoUpdated() { var _this2 = this; this.emit(TokenAuthService.INFO_UPDATED, this.info); var deadline = this.info.deadline; if (deadline == null || this.config.refreshToken == null) { return; } var delta = deadline - Date.now(); if (delta > 0) { window.clearTimeout(this.refreshTimer); this.refreshTimer = window.setTimeout(function () { _this2.refresh(); }, Math.floor(delta * 0.7)); } }; _proto.handleAuthSuccess = function handleAuthSuccess() { if (this.config.onAuthSuccess) { this.config.onAuthSuccess(this.info); } }; _createClass(TokenAuthService, [{ key: "storage", get: function get() { return this.config && this.config.storage || window.sessionStorage; } }]); return TokenAuthService; }(EventEmitter); TokenAuthService.INFO_UPDATED = 'info-updated';