{"version":3,"file":"uofx-core-interceptor.mjs","sources":["../../interceptor/src/base-handler.logic.ts","../../interceptor/src/error-handler.logic.ts","../../interceptor/src/interceptor.logic.ts","../../interceptor/uofx-core-interceptor.ts"],"sourcesContent":["import { HttpRequest } from '@angular/common/http';\r\nimport { ErrorMessageModel } from '@uofx/core';\r\n\r\n/** UOF 專用 Request 物件，用於紀錄重新嘗試次數 */\r\nexport class UofxHttpRequest<T> extends HttpRequest<T> {\r\n  /** 已重新嘗試的次數 */\r\n  retryCount?= 0;\r\n}\r\n\r\nexport abstract class UofxBaseHttpHandler {\r\n\r\n  /** 取得 Token */\r\n  abstract getToken(): string;\r\n  /** 設定 Token */\r\n  abstract setToken(value: string, isRefresh?: boolean);\r\n  /** 設定 Token 到期時間(秒) */\r\n  abstract setTokenExp(value: string);\r\n  /** 取得 CorpId */\r\n  abstract getCorpId(): string;\r\n  /** 取得API版本 */\r\n  abstract getApiVersion(): string;\r\n\r\n\r\n  /** Request error status 400 */\r\n  abstract error400(errorMessage: ErrorMessageModel);\r\n  /** Request error status 400 模組授權數量已滿、帳號授權數已滿、沒有授權 */\r\n  abstract error400LicenseFull(errorMessage: ErrorMessageModel);\r\n  /** Request error status 400 站台版本已升級, 需重新整理頁面 */\r\n  abstract error400VersionUpdate(errorMessage: ErrorMessageModel);\r\n  /** Request error status 401 */\r\n  abstract error401(errorMessage: string, url?: string): void;\r\n  /** Request error status 403 無存取權限 */\r\n  abstract error403(): void;\r\n  /** Request error status 404 找不到資料 */\r\n  abstract error404(errorMessage: ErrorMessageModel): void;\r\n  /** Request error status 500 */\r\n  abstract error500(errorMessage: ErrorMessageModel): void;\r\n  /** 可能發生504錯誤的情境(查詢、寫入處理時間過久、測試連線) */\r\n  abstract error504(errorMessage: ErrorMessageModel): void;\r\n\r\n  /** Request error others */\r\n  abstract errorDefault(errorMessage: ErrorMessageModel);\r\n\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { HttpErrorResponse } from '@angular/common/http';\r\nimport { ErrorHandler } from '@angular/core';\r\nimport {\r\n  ErrorMessageModel,\r\n  ErrorType,\r\n  UofxExceptionKeeper,\r\n  ExceptionModel,\r\n  MsicErrorCode,\r\n  UofxConsole\r\n} from '@uofx/core';\r\nimport { TimeoutError } from 'rxjs';\r\n\r\nexport class UofxHttpErrorHandlerLogic extends ErrorHandler {\r\n  /** 紀錄錯誤訊息到 Client 端 */\r\n  static unexpectedErrorHandler(error: string | Error, type: string = 'client') {\r\n    let errMsg = '';\r\n    if (error instanceof Error) {\r\n      errMsg = error.stack ? error.stack : error.message;\r\n    } else {\r\n      errMsg = error;\r\n    }\r\n    UofxExceptionKeeper.keep(new ExceptionModel(type, errMsg));\r\n  }\r\n\r\n  /**\r\n   * 錯誤處理\r\n   * @param error 錯誤\r\n   */\r\n  static httpErrorHandler(error: any): ErrorMessageModel | string | null {\r\n\r\n    // 先檢查 event 型別是否為 HttpErrorResponse 或 TimeoutError\r\n    if (!(error instanceof HttpErrorResponse) && !(error instanceof TimeoutError)) return null;\r\n\r\n    let errMsg = null;\r\n\r\n    if (!(error['status'])) {\r\n      errMsg = this._errorNoStatus(error);\r\n    } else {\r\n      error = error as HttpErrorResponse;\r\n      if (error.status === 400) errMsg = this._error400(error);\r\n      else if (error.status === 401) errMsg = this._error401(error);\r\n      else if (\r\n        error.status === 501 ||\r\n        error.status === 503 ||\r\n        error.status === 505) {\r\n        errMsg = this._error500(error);\r\n      }\r\n      else errMsg = this._errorOther(error);\r\n    }\r\n\r\n    if (!errMsg || !errMsg.type) {\r\n      UofxConsole.error(error);\r\n    }\r\n\r\n    return errMsg;\r\n  }\r\n\r\n  /** @internal No Status 錯誤，不記錄 Log 在 Client 端 */\r\n  static _errorNoStatus(httpError: HttpErrorResponse | TimeoutError): ErrorMessageModel {\r\n    const errMsg: ErrorMessageModel = <ErrorMessageModel>{\r\n      type: ErrorType.Msic\r\n    };\r\n    if (navigator.onLine === false) {\r\n      // 沒有網路\r\n      errMsg.code = MsicErrorCode.ClientNetworkOffline;\r\n    } else if (httpError instanceof TimeoutError) {\r\n      // 逾時\r\n      errMsg.code = MsicErrorCode.NetworkTimeout;\r\n    } else if (httpError.status === 0 && httpError.url === null) {\r\n      // Server CORS\r\n      errMsg.code = MsicErrorCode.ServerCORSNotEnabled;\r\n    } else {\r\n      errMsg.code = MsicErrorCode.Unknown;\r\n      errMsg.message = httpError.message;\r\n      errMsg.errorId = httpError?.error?.errorId?.toString();\r\n    }\r\n\r\n    return errMsg;\r\n  }\r\n\r\n  /** @internal 400 錯誤，商業邏輯錯誤不記錄 Log 在 Client 端 */\r\n  static _error400(httpError: HttpErrorResponse): ErrorMessageModel {\r\n    if (!httpError.error) return null;\r\n\r\n    const body = httpError.error;\r\n    const errMsg: ErrorMessageModel = <ErrorMessageModel>{};\r\n    const type = body.type as ErrorType;\r\n\r\n    if (type === ErrorType.DidBadRequest) {\r\n      // 商業邏輯錯誤\r\n      errMsg.type = type;\r\n      errMsg.codes = body.errors ? body.errors : [];\r\n      errMsg.moreErrors = body.moreErrors ? body.moreErrors : [];\r\n    } else if (type === ErrorType.InvalidModelState) {\r\n      // 後端 Model 驗證錯誤\r\n      errMsg.type = type;\r\n      errMsg.message = JSON.stringify(body.errors);\r\n    } else {\r\n      errMsg.type = ErrorType.Unknown;\r\n      errMsg.message = '400 Unknown';\r\n    }\r\n\r\n    if (errMsg.type === ErrorType.InvalidModelState || errMsg.type === ErrorType.Unknown) {\r\n      this._exceptionKeeper(errMsg.message, errMsg.type);\r\n    }\r\n\r\n    return errMsg;\r\n  }\r\n\r\n  /** @internal 401 錯誤，token不存在，不會記錄 Log 在 Client 端 */\r\n  static _error401(httpError: HttpErrorResponse): string {\r\n    // 目前401、403會是這種格式，400則是ErrorMessageModel。\r\n    // {\r\n    //   \"ErrorMessage\": \"CMN-AUTH-E11\",\r\n    //   \"ErrorId\": \"OH3B3ZZ32GXEXJXO6G7CJQASRI\"\r\n    // }\r\n    if (!httpError.error) return null;\r\n\r\n    return httpError.error.errorMessage;\r\n  }\r\n\r\n  /** @internal 500 錯誤，會記錄 Log 在 Client 端 */\r\n  static _error500(httpError: HttpErrorResponse): ErrorMessageModel {\r\n    if (!httpError.error) return null;\r\n\r\n    const body = httpError.error;\r\n    const errMsg: ErrorMessageModel = <ErrorMessageModel>{\r\n      type: ErrorType.Exception,\r\n      code: body.status\r\n    };\r\n\r\n    if (body.message) {\r\n      errMsg.message = body.message;\r\n    } else {\r\n      errMsg.message = JSON.stringify(httpError);\r\n    }\r\n\r\n    this._exceptionKeeper(errMsg.message, errMsg.type);\r\n\r\n    return errMsg;\r\n  }\r\n\r\n  /** @internal 其餘錯誤，不記錄 Log 在 Client 端 */\r\n  static _errorOther(httpError: HttpErrorResponse): ErrorMessageModel {\r\n    const errMsg: ErrorMessageModel = <ErrorMessageModel>{};\r\n\r\n    errMsg.type = ErrorType.Msic;\r\n    errMsg.code = httpError.status.toString();\r\n    errMsg.message = httpError.statusText;\r\n    errMsg.errorId = httpError?.error?.errorId?.toString();\r\n\r\n    return errMsg;\r\n  }\r\n\r\n  /** @internal 紀錄錯誤訊息 */\r\n  static _exceptionKeeper(message: any, eventId: string) {\r\n    UofxExceptionKeeper.keep(new ExceptionModel('server', message, eventId));\r\n  }\r\n\r\n  public handleError(error: HttpErrorResponse | Error | string) {\r\n\r\n    if (!(error instanceof HttpErrorResponse)) {\r\n      UofxHttpErrorHandlerLogic.unexpectedErrorHandler(error);\r\n    }\r\n\r\n    super.handleError(error);\r\n  }\r\n}\r\n\r\n","import {\r\n  Config,\r\n  ErrorMessageModel,\r\n  ErrorType,\r\n  ExceptionModel,\r\n  Helper,\r\n  UofxConsole,\r\n  UofxExceptionKeeper\r\n} from '@uofx/core';\r\nimport {\r\n  EMPTY,\r\n  Observable,\r\n  Subject,\r\n  of,\r\n  throwError\r\n} from 'rxjs';\r\nimport { HttpErrorResponse, HttpResponse } from '@angular/common/http';\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { UofxBaseHttpHandler } from './base-handler.logic';\r\nimport { UofxHttpErrorHandlerLogic } from './error-handler.logic';\r\nimport jwt_decode from 'jwt-decode';\r\nimport { tap } from 'rxjs/operators';\r\n\r\n@Injectable()\r\nexport class UofxInterceptorLogic {\r\n\r\n  /** @private 登入者的 Token */\r\n  get Token(): string {\r\n    return this.httpHandler.getToken();\r\n  }\r\n  set Token(value: string) {\r\n    this.httpHandler.setToken(value);\r\n  }\r\n\r\n  private exeHttps: Array<string> = [];\r\n  exeHttpSub$ = new Subject<boolean>();\r\n\r\n  constructor(\r\n    private httpHandler: UofxBaseHttpHandler\r\n  ) { }\r\n\r\n  /**\r\n   * 判斷url是否為api發出\r\n   * @param url request rul\r\n   * @returns boolean\r\n   * @memberof InterceptorLogic\r\n   */\r\n  isApiUrl(url: string) {\r\n    const lowerUrl = url.toLocaleLowerCase();\r\n    return lowerUrl.startsWith('~/api') || lowerUrl.startsWith('~/openapi');\r\n  }\r\n\r\n  /**\r\n   * 轉換成 API 的 URL\r\n   * @param requestUrl request rul\r\n   * @returns 轉換過的url\r\n   */\r\n  transApiUrl(requestUrl: string) {\r\n    if (!this.isApiUrl(requestUrl)) return requestUrl;\r\n\r\n    const apiVersion = this.httpHandler.getApiVersion();\r\n    const apiUrl = Helper.transUrl(requestUrl);\r\n\r\n    if (!apiVersion) UofxConsole.error('Cannot get API version info from meta data.');\r\n\r\n    const apiVersionUrl = Helper.addApiVersion(apiVersion, apiUrl);\r\n    const resultUrl = Config.serverUrl + Helper.replaceUrlDoubleSlash(apiVersionUrl);\r\n    return resultUrl;\r\n  }\r\n\r\n  /**\r\n   * 取得授權的 Headers\r\n   * @param contentType 預設為 'application/json;'\r\n   */\r\n  getAuthHeaders(contentType: string = 'application/json;') {\r\n    if (!this.Token) return {};\r\n\r\n    const result = {\r\n      Authorization: this.Token\r\n    };\r\n\r\n    // 後台沒有corpId，所以先判斷有值再加入header\r\n    if (this.httpHandler.getCorpId()) {\r\n      result['CorpId'] = this.httpHandler.getCorpId();\r\n    }\r\n\r\n    if (contentType)\r\n      result['Content-Type'] = contentType;\r\n\r\n    return result;\r\n  }\r\n\r\n  /** 設定執行中連線 */\r\n  setExeHttp(obs: Observable<any>, url: string): Observable<any> {\r\n    this.exeHttps.push(url);\r\n    this.exeHttpSub$.next(true);\r\n\r\n    const findAndRemove = () => {\r\n      const find = this.exeHttps.indexOf(url);\r\n      if (find > -1) this.exeHttps.splice(find, find + 1);\r\n      if (this.exeHttps.length === 0) {\r\n        this.exeHttpSub$.next(false);\r\n      }\r\n    };\r\n\r\n    // zip 將 request 包裹的話，不會經過 complete 事件\r\n    // next 會拋出兩次事件，第一次的回傳值是 { type: 0 }\r\n    return obs.pipe(tap({\r\n      next: (res) => {\r\n        if (res.type !== 0) findAndRemove();\r\n      },\r\n      error: () => {\r\n        findAndRemove();\r\n      }\r\n    }));\r\n  }\r\n\r\n  /**\r\n   * 錯誤處理或頁面導向\r\n   * @param event {(HttpResponse<any> | HttpErrorResponse)}\r\n   * @param url\r\n   * @returns Observable<any>\r\n   * @memberof InterceptorLogic\r\n   */\r\n  handleResponse(event: HttpResponse<any> | HttpErrorResponse, url: string): Observable<any> {\r\n    // 上傳檔案url傳進來時已經會套用serverUrl，需另外判斷。\r\n    const isCallAPI = url.toLocaleLowerCase().startsWith('~/api') || url.toLocaleLowerCase().includes('base/file');\r\n    const isI18nAPI = url.toLocaleLowerCase().includes('/trans/lang/');\r\n    if (!isCallAPI) {\r\n      if (event instanceof HttpErrorResponse) {\r\n        return throwError(() => event);\r\n      } else {\r\n        return of(event);\r\n      }\r\n    } else if (isI18nAPI) {\r\n      // 取得多語系時發生錯誤，站台還是照樣登入，不攔截錯誤\r\n      if (event instanceof HttpErrorResponse) {\r\n        UofxExceptionKeeper.keep(new ExceptionModel('i18n', event.message));\r\n      }\r\n      return of(this._i18nApiResponse(event));\r\n    }\r\n\r\n    let errMsg: ErrorMessageModel | string;\r\n    this._handleSetToken(event);\r\n\r\n    // 先記錄 error 再轉頁 (等error page定義好再將接到的 messageModel 傳入)\r\n    if (event.status !== 200 && event.status !== 204) {\r\n      errMsg = UofxHttpErrorHandlerLogic.httpErrorHandler(event);\r\n    }\r\n\r\n    switch (event.status) {\r\n      case 200:\r\n      case 204:\r\n        if (event instanceof HttpResponse) {\r\n          const newEvent = this._handleResponseBody(event);\r\n          return of(newEvent);\r\n        }\r\n        return of(event);\r\n\r\n      case 400:\r\n        // 1.模組授權數量已滿\r\n        const isModuleLicenseFull = this._apiErrorCode(errMsg as ErrorMessageModel, ErrorModel.ModuleAuthCountFull);\r\n        // 2.帳號授權數已滿\r\n        const isAccLicenseFull = this._apiErrorCode(errMsg as ErrorMessageModel, ErrorModel.AccountAuthCountFull);\r\n        // 3.沒有授權\r\n        const isLicenseNotDefined = this._apiErrorCode(errMsg as ErrorMessageModel, ErrorModel.LicenseNotDefined);\r\n        // 4.站台版本已升級, 需重新整理頁面\r\n        const versionUpdate = this._apiErrorCode(errMsg as ErrorMessageModel, ErrorModel.VersionUpdate);\r\n\r\n        if (isModuleLicenseFull || isAccLicenseFull || isLicenseNotDefined) {\r\n          this.httpHandler.error400LicenseFull(errMsg as ErrorMessageModel);\r\n          return EMPTY;\r\n        } else if (versionUpdate) {\r\n          this.httpHandler.error400VersionUpdate(errMsg as ErrorMessageModel);\r\n          return EMPTY;\r\n        } else {\r\n          // 4.其他 400 錯誤\r\n          const result = this.httpHandler.error400(errMsg as ErrorMessageModel);\r\n          if (result) return result;\r\n        }\r\n        break;\r\n\r\n      case 401:\r\n        /**\r\n         * Token失效\r\n         * 1. G-CMN-AUTH-E01 (未分類)\r\n         * 2. G-CMN-AUTH-E06 (強制登出: 線上人員管理強制登出)\r\n         * 3. G-CMN-AUTH-E07 (公司層級的強制登出: 公司停用、公司刪除、公司代號改變)\r\n         */\r\n        this.httpHandler.error401(errMsg as string, url);\r\n        return throwError(() => new Error('Token is Invalid!'));\r\n\r\n      case 403:\r\n        this.httpHandler.error403();\r\n        return EMPTY;\r\n\r\n      case 404:\r\n        this.httpHandler.error404(errMsg as ErrorMessageModel);\r\n        return EMPTY;\r\n\r\n      case 500:\r\n        this.httpHandler.error500(errMsg as ErrorMessageModel);\r\n        return EMPTY;\r\n\r\n      case 504:\r\n        this.httpHandler.error504(errMsg as ErrorMessageModel);\r\n        return EMPTY;\r\n\r\n      default:\r\n        return this.httpHandler.errorDefault(errMsg as ErrorMessageModel);\r\n    }\r\n  }\r\n\r\n  private _i18nApiResponse(event: HttpResponse<any> | HttpErrorResponse) {\r\n    if (event instanceof HttpErrorResponse) {\r\n      const getNewEvent = new HttpResponse({ status: 200, statusText: 'ok', body: {}, url: event.url });\r\n      return getNewEvent;\r\n    }\r\n    return event;\r\n  }\r\n\r\n  /**\r\n   * @private Set token\r\n   * @param event (HttpResponse<any> | HttpErrorResponse)\r\n   * @memberof InterceptorLogic\r\n   */\r\n  _handleSetToken(event: HttpResponse<any> | HttpErrorResponse) {\r\n    if (!event.headers) return;\r\n    const setToken = event.headers.get('set-token');\r\n    const refreshToken = event.headers.get('refresh-token');\r\n\r\n    if (setToken || refreshToken) {\r\n      const token = refreshToken ?? setToken;\r\n      // 設定token到期時間(為了逾時前的倒數功能)\r\n      this._setTokenExp(token);\r\n\r\n      this.httpHandler.setToken(token, refreshToken ? true : false);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @private 設定token到期時間(為了逾時前的倒數功能)\r\n   * @param {string} token\r\n   * @memberof UofxInterceptorLogic\r\n   */\r\n  private _setTokenExp(token: string) {\r\n    // 多語系api沒有token&預防token被亂塞造成攔截器有誤，這裡用try catch包起來。\r\n    try {\r\n      const decodedToken = jwt_decode(token);\r\n      const expiredSeconds = decodedToken['exp'];\r\n      this.httpHandler.setTokenExp(expiredSeconds);\r\n    } catch (error) { }\r\n  }\r\n\r\n  /**\r\n   * @private Process response body.\r\n   * @param event HttpResponse<any>\r\n   * @returns\r\n   * @memberof InterceptorLogic\r\n   */\r\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n  _handleResponseBody(event: HttpResponse<any>) {\r\n    const body = event.body;\r\n    // 有兩種回傳結果\r\n    // 1.API 回傳的結果會在body.model裡面(由於body有可能會null所以做此判斷)\r\n    // 2.取得檔案的回傳結果會直接在body底下。\r\n    const resultBody = (body && body.model !== undefined) ? body.model : body;\r\n    return event.clone({\r\n      body: resultBody\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Get API error code\r\n   * @param {ErrorMessageModel} errorModel 錯誤訊息\r\n   * @param {string} errCode 要找的錯誤代碼\r\n   */\r\n  _apiErrorCode(errorModel: ErrorMessageModel, errCode: string) {\r\n    if (errorModel.type === ErrorType.DidBadRequest && errorModel.codes.length > 0) {\r\n      return errorModel.codes.some(item => item === errCode);\r\n    }\r\n    return false;\r\n  }\r\n}\r\n\r\n/**\r\n * 攔截器獨立使用的error code\r\n * -\r\n * build @uofx-core的時候就不用刻意相依整包@uofx-error-code，同時也減輕套件升版的流程\r\n * @export\r\n * @class ErrorModel\r\n */\r\nexport class ErrorModel {\r\n  /** 模組授權數已滿 */\r\n  static ModuleAuthCountFull = 'G-CMN-AUTH-E03';\r\n  /** 帳號授權數已滿 */\r\n  static AccountAuthCountFull = 'G-CMN-AUTH-E04';\r\n  /** 沒有授權 */\r\n  static LicenseNotDefined = 'G-CMN-AUTH-E05';\r\n  /** 站台版本已升級, 需重新整理頁面 */\r\n  static VersionUpdate = 'G-CMN-ERR-E13';\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.UofxBaseHttpHandler"],"mappings":"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"}