UNPKG

@mamba-le/auth

Version:
337 lines (334 loc) 9.72 kB
import lodash from 'lodash'; import { BindAll } from 'lodash-decorators'; import { computed, toJS } from 'mobx'; import { lastValueFrom, Subject, zip } from 'rxjs'; import { AuthController, IAuthOptions } from './auth'; import env from './env'; import { InfoController } from './info'; import { AuthOptions } from './options'; declare global { interface Window { __MICRO_APP_ENVIRONMENT__: boolean; rawWindow: Window; /** * 挂载的顶层 PortalAuthController * @type {PortalAuthController} * @memberof Window */ PortalAuth: PortalAuthController; } } export interface IPortalAuthOptions { /** * Portal 类型 * @type {('General' | 'BP' | 'SP')} * @memberof IPortalAuthOptions */ PortalType?: 'General' | 'BP' | 'SP' /** * Token 类型 * @type {('JWT' | 'Other')} * @memberof IPortalAuthOptions */ TokenType?: 'JWT' | 'Other' BPAuth?: IAuthOptions SPAuth?: IAuthOptions } /** * Portal 认证信息 BP&SP * @export * @class PortalAuthController */ @BindAll() export class PortalAuthController { static get env() { return env } get env() { return env } /** * 存储的单列 * @private * @static * @type {PortalAuthController} * @memberof PortalAuthController */ protected static PortalAuth: PortalAuthController = undefined; /** * 混合认证 * @protected * @static * @type {AuthController} * @memberof PortalAuthController */ protected static GeneralAuth: AuthController = undefined; /** * BP 认证 * @protected * @static * @type {AuthController} * @memberof PortalAuthController */ protected static BPAuth: AuthController = undefined; /** * SP 认证 * @protected * @static * @type {AuthController} * @memberof PortalAuthController */ protected static SPAuth: AuthController = undefined; /** * 基础信息 * @protected * @static * @type {InfoController} * @memberof PortalAuthController */ protected static PortalInfo: InfoController = undefined; /** * 引流信息 * @protected * @static * @type {InfoController} * @memberof PortalAuthController */ protected static PortalDrainage: InfoController = undefined; protected static createAuth(options: IPortalAuthOptions) { switch (options.PortalType) { case 'BP': PortalAuthController.BPAuth = new AuthController({ CookieKey: ['BPPORTAL_TOKEN'], StorageKey: 'BPPortal', TokenType: options.TokenType || 'JWT' }) return case 'SP': PortalAuthController.SPAuth = new AuthController({ CookieKey: ['SALES_TOKEN'], StorageKey: 'SALESPortal', TokenType: options.TokenType || 'Other' }) return default: PortalAuthController.GeneralAuth = new AuthController({ CookieKey: ['BPPORTAL_TOKEN', 'SALES_TOKEN'], StorageKey: 'Portal', TokenType: options.TokenType || 'Other' }) } }; constructor(protected readonly options: IPortalAuthOptions = { PortalType: 'BP' }) { // 浏览器 if (AuthOptions.browser) { // 微前端 环境中 if (AuthOptions.micro && window?.rawWindow?.PortalAuth) { PortalAuthController.PortalAuth = window.rawWindow.PortalAuth } else if (window?.PortalAuth) { PortalAuthController.PortalAuth = window.PortalAuth } // 非微前端环境 if (!AuthOptions.micro) { window.PortalAuth = this } // 单例 if (PortalAuthController.PortalAuth) { return PortalAuthController.PortalAuth; } } PortalAuthController.createAuth(this.options); PortalAuthController.PortalInfo = new InfoController({ StorageKey: 'PortalInfo' }); PortalAuthController.PortalDrainage = new InfoController({ StorageKey: 'PortalDrainage' }); this.createHydrate(); PortalAuthController.PortalAuth = this; AuthOptions.log('PortalAuth', this) } /** * 持久化初始化完成 Subject * @type {Promise<any>} * @memberof ControllerUser */ protected readonly HydrateSubject = new Subject<Boolean>(); /** * 持久化初始化完成 Promise * @type {Promise<any>} * @memberof ControllerUser */ get HydrateAsync(): Promise<this> { return lastValueFrom(this.HydrateSubject, { defaultValue: undefined }); } /** * 异步 HydrateSubject 已经完成 * @readonly * @memberof PortalAuthController */ get HydrateisStopped() { return this.HydrateSubject.isStopped } /** * BP Auth * @type {AuthController} * @memberof PortalAuthController */ protected get BPAuth() { return PortalAuthController.BPAuth } /** * SP Auth * @type {AuthController} * @memberof PortalAuthController */ protected get SPAuth() { return PortalAuthController.SPAuth } /** * 通用的 Auth * @type {AuthController} * @memberof PortalAuthController */ protected get GeneralAuth() { return PortalAuthController.GeneralAuth } /** * 数据 Info * @readonly * @memberof PortalAuthController */ protected get PortalInfo() { return PortalAuthController.PortalInfo } /** * 数据 引流 * @readonly * @protected * @memberof PortalAuthController */ protected get PortalDrainage() { return PortalAuthController.PortalDrainage } /** * 基础数据 * @readonly * @memberof PortalAuthController */ @computed get Info() { return toJS(this.PortalInfo.value) } /** * 引流数据 * @readonly * @memberof PortalAuthController */ @computed get Drainage() { return toJS(this.PortalDrainage.value) } /** * AccessToken 返回校验 时间是否过期 过期 的 AccessToken 不返回 * @readonly * @memberof PortalAuthController */ @computed get AccessToken() { switch (this.options.PortalType) { case 'BP': return this.BPAuth.AccessToken case 'SP': return this.SPAuth.AccessToken default: return this.GeneralAuth.AccessToken } } /** * AccessToken 解码信息 * @readonly * @memberof PortalAuthController */ @computed get JwtDecoded() { switch (this.options.PortalType) { case 'BP': return this.BPAuth.JwtDecoded case 'SP': return this.SPAuth.JwtDecoded default: return this.GeneralAuth.JwtDecoded } } /** * 保存 AccessToken 校验有效性 无效过滤 * @param {string} [AccessToken=undefined] * @memberof PortalAuthController */ onSaveAccessToken(AccessToken: string = undefined, setCookie = false) { this.BPAuth?.onSaveAccessToken(AccessToken, setCookie) this.SPAuth?.onSaveAccessToken(AccessToken, setCookie) this.GeneralAuth?.onSaveAccessToken(AccessToken, setCookie) } /** * 存储info 信息 * @param {*} value * @memberof PortalAuthController */ onSaveInfo(value: any) { this.PortalInfo.onSave(value) AuthOptions.trace('Save Info', value) } /** * 存储 Drainage 信息 * @param {*} value * @memberof PortalAuthController */ onSaveDrainage(value: any) { this.PortalDrainage.onSave(value) AuthOptions.trace('Save Drainage', value) } /** * 清理所有的登录信息 * @return {*} * @memberof AuthController */ async onClear() { try { AuthOptions.writeCheck() AuthOptions.trace('clear start') this.BPAuth?.onClear() this.SPAuth?.onClear() this.GeneralAuth?.onClear() this.PortalInfo?.onClear() this.PortalDrainage?.onClear() if (AuthOptions.browser) { window.localStorage?.clear() window.sessionStorage?.clear() await this.HydrateAsync await AuthOptions.LocalForage.clear(); } AuthOptions.log('clear success', 'localStorage,sessionStorage,IndexedDB,cookie 全部清理') } catch (error) { AuthOptions.trace('clear error', error) } } /** * 创建持久化存储 * @memberof BaseModel */ protected async createHydrate() { try { const observables = lodash.compact([ this.BPAuth?.HydrateAsync, this.SPAuth?.HydrateAsync, this.GeneralAuth?.HydrateAsync, this.PortalInfo?.HydrateAsync ]) await lastValueFrom(zip(observables), { defaultValue: undefined }) this.HydrateSubject.next(true) this.HydrateSubject.complete() } catch (error) { AuthOptions.trace('error', error) this.HydrateSubject.next(false) this.HydrateSubject.complete() } } }