{"version":3,"file":"idea-ionic-auth0.mjs","sources":["../../../modules/auth0/src/auth0.module.ts","../../../modules/auth0/src/auth0.service.ts","../../../modules/auth0/src/auth0.guard.ts","../../../modules/auth0/idea-ionic-auth0.ts"],"sourcesContent":["import { APP_INITIALIZER, NgModule } from '@angular/core';\nimport { AuthModule, AuthClientConfig } from '@auth0/auth0-angular';\nimport { IDEAEnvironment } from '@idea-ionic/common';\n\nconst injectConfig = (env: any, config: AuthClientConfig): (() => void) => {\n  return (): void =>\n    config.set({\n      domain: env.auth0.domain,\n      clientId: env.auth0.clientId,\n      useRefreshTokens: env.auth0.storeRefreshToken,\n      cacheLocation: env.auth0.storeRefreshToken ? 'localstorage' : 'memory',\n      authorizationParams: { redirect_uri: env.auth0.callbackUri || window.location.origin }\n    });\n};\n\n@NgModule({\n  imports: [AuthModule.forRoot()],\n  providers: [\n    { provide: APP_INITIALIZER, useFactory: injectConfig, deps: [IDEAEnvironment, AuthClientConfig], multi: true }\n  ]\n})\nexport class IDEAAuth0Module {}\n","import { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthService } from '@auth0/auth0-angular';\nimport { Platform } from '@ionic/angular/standalone';\nimport { Browser } from '@capacitor/browser';\nimport { Auth0User } from 'idea-toolbox';\nimport { IDEAEnvironment } from '@idea-ionic/common';\n\n@Injectable({ providedIn: 'root' })\nexport class IDEAAuth0Service {\n  protected _env = inject(IDEAEnvironment);\n  private _platform = inject(Platform);\n  private _auth0 = inject(AuthService);\n\n  /**\n   * The internal Auth0's service.\n   */\n  get __raw(): AuthService {\n    return this._auth0;\n  }\n\n  private isMobileDevice(): boolean {\n    return this._platform.is('capacitor');\n  }\n\n  /**\n   * Open (if needed) Auth0's Universal Login page, to authenticate a user.\n   * @param afterRedirectTo where to go after a successful login\n   */\n  goToLogin(afterRedirectTo?: string): void {\n    this.isMobileDevice() ? this.loginWithMobile(afterRedirectTo) : this.loginWithSPA(afterRedirectTo);\n  }\n  private async loginWithSPA(afterRedirectTo?: string): Promise<void> {\n    await firstValueFrom(this._auth0.loginWithRedirect({ appState: { target: afterRedirectTo } }));\n  }\n  private async loginWithMobile(afterRedirectTo?: string): Promise<void> {\n    await firstValueFrom(\n      this._auth0.loginWithRedirect({ appState: { target: afterRedirectTo }, openUrl: url => Browser.open({ url }) })\n    );\n  }\n\n  /**\n   * Open (if needed) Auth0's Universal Login page, to logout a user.\n   */\n  goToLogout(): void {\n    this.isMobileDevice() ? this.logoutWithMobile() : this.logoutWithSPA();\n  }\n  private async logoutWithSPA(): Promise<void> {\n    await firstValueFrom(this._auth0.logout({ logoutParams: { returnTo: document.location.origin } }));\n  }\n  private async logoutWithMobile(): Promise<void> {\n    await firstValueFrom(\n      this._auth0.logout({ logoutParams: { localOnly: true }, openUrl: url => Browser.open({ url }) })\n    );\n  }\n\n  /**\n   * Handle the callback after a login or logout in Auth0 Universal Login page.\n   * In order to work, it has to be used in `app.component.ts`, as explained in the following snippet:\n   * ```\n      export class AppComponent {\n        constructor(private ngZone: NgZone, private auth0: IDEAAuth0Service) {\n          App.addListener('appUrlOpen', ({ url }): void =>\n            this.ngZone.run((): void => this.auth0.handleCallbackOnMobileDevices(url))\n          );\n        }\n      }\n   * ```\n   */\n  async handleCallbackOnMobileDevices(url: string): Promise<void> {\n    if (url?.startsWith(this._env.auth0.callbackUri)) {\n      if (url.includes('state=') && (url.includes('error=') || url.includes('code=')))\n        await firstValueFrom(this._auth0.handleRedirectCallback(url));\n      await Browser.close();\n    }\n  }\n\n  /**\n   * Get the ID token, to use for authenticating API requests to the back-end.\n   */\n  async getIdToken(): Promise<string> {\n    const { __raw } = await firstValueFrom(this._auth0.idTokenClaims$);\n    return __raw;\n  }\n  /**\n   * Whether the user is currently authenticated.\n   */\n  async isUserAuthenticated(): Promise<boolean> {\n    return await firstValueFrom(this._auth0.isAuthenticated$);\n  }\n  /**\n   * Get the current user and its data.\n   */\n  async getUser(): Promise<Auth0User> {\n    const user = await firstValueFrom(this._auth0.user$);\n    if (user) return new Auth0User(user);\n    else return null;\n  }\n}\n","import { inject } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot } from '@angular/router';\nimport { firstValueFrom } from 'rxjs';\nimport { IDEAApiService } from '@idea-ionic/common';\n\nimport { IDEAAuth0Service } from './auth0.service';\n\nexport const auth0Guard: CanActivateFn = async (\n  _: ActivatedRouteSnapshot,\n  state: RouterStateSnapshot\n): Promise<boolean> => {\n  const _auth = inject(IDEAAuth0Service);\n  const _api = inject(IDEAApiService);\n\n  if (!_api.authToken)\n    _api.authToken = async (): Promise<string> => {\n      try {\n        return getValidIdToken(_auth);\n      } catch (error) {\n        _auth.goToLogin(state.url);\n        return null;\n      }\n    };\n\n  if (await _auth.isUserAuthenticated()) return true;\n  else {\n    _auth.goToLogin(state.url);\n    return false;\n  }\n};\n\n/**\n * Get a valid ID token from the cache or, if expired, from the server.\n * Note: Auth0 consider the cache valid even if the ID Token expried (only checks for valid Access Tokens).\n */\nconst getValidIdToken = async (auth: IDEAAuth0Service): Promise<string> => {\n  const cacheRes = await firstValueFrom(auth.__raw.getAccessTokenSilently({ detailedResponse: true }));\n\n  const { exp } = decodeJwt(cacheRes.id_token);\n  const isTokenExpired = new Date(exp * 1000) < new Date();\n\n  if (!isTokenExpired) return cacheRes.id_token;\n  else {\n    const freshRes = await firstValueFrom(\n      auth.__raw.getAccessTokenSilently({ detailedResponse: true, cacheMode: 'off' })\n    );\n    return freshRes.id_token;\n  }\n};\n\n/**\n * Decode a JWT without relying on external libraries.\n */\nconst decodeJwt = (token: string): Record<string, any> => {\n  const base64Url = token.split('.')[1];\n  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n  const jsonPayload = decodeURIComponent(\n    window\n      .atob(base64)\n      .split('')\n      .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n      .join('')\n  );\n  return JSON.parse(jsonPayload);\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}