{"version":3,"file":"starchild-auth.umd.cjs","sources":["../src/utils.ts","../src/StarchildAuth.ts"],"sourcesContent":["/**\n * Generate a cryptographically random nonce for CSRF protection.\n * Falls back to Math.random if the Web Crypto API is unavailable.\n */\nexport function generateNonce(): string {\n  try {\n    const arr = new Uint8Array(16)\n    crypto.getRandomValues(arr)\n    return Array.from(arr, (b) => b.toString(16).padStart(2, '0')).join('')\n  } catch {\n    return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2)\n  }\n}\n\n/**\n * Calculate centered popup window features string.\n */\nexport function popupFeatures(width: number, height: number): string {\n  const left = Math.max(0, Math.round((screen.width - width) / 2))\n  const top = Math.max(0, Math.round((screen.height - height) / 2))\n  return [\n    `width=${width}`,\n    `height=${height}`,\n    `left=${left}`,\n    `top=${top}`,\n    'scrollbars=yes',\n    'resizable=yes',\n    'status=no',\n    'toolbar=no',\n    'menubar=no',\n    'location=no',\n  ].join(',')\n}\n","import type {\n  StarchildAuthOptions,\n  UserInfo,\n  LoginResult,\n  StarchildMessage,\n  AuthSuccessMessage,\n} from './types'\nimport { generateNonce, popupFeatures } from './utils'\n\nconst DEFAULT_ORIGIN = 'https://iamstarchild.com'\nconst DEFAULT_API_BASE = 'https://go-api.iamstarchild.com/v1'\nconst DEFAULT_CHAT_API_BASE = 'https://ai-api.iamstarchild.com'\nconst DEFAULT_POPUP_WIDTH = 480\nconst DEFAULT_POPUP_HEIGHT = 640\nconst DEFAULT_REFRESH_INTERVAL = 12 * 60 * 1000 // 12 minutes\n\ninterface PendingLogin {\n  resolve: (result: LoginResult) => void\n  reject: (error: Error) => void\n  state: string\n}\n\n/**\n * Starchild Auth SDK (V2) — enables third-party websites to integrate Starchild SSO login\n * via the OAuth Client registration model.\n *\n * Key differences from V1:\n * - `clientId` is required\n * - Token refresh uses direct API calls instead of hidden iframes\n * - `refreshToken` is persisted in localStorage for session restoration\n *\n * @example\n * ```ts\n * const auth = new StarchildAuth({\n *   clientId: 'your-client-id',\n *   onLogin: ({ accessToken, refreshToken, expiresIn, userInfo }) => {\n *     console.log('Logged in as', userInfo.agentName)\n *   },\n *   onTokenRefresh: (newToken) => {\n *     // Update your stored token\n *   },\n *   onTokenRefreshFailed: () => {\n *     // Session expired, prompt re-login\n *   },\n * })\n *\n * // User clicks \"Sign in\"\n * const { accessToken, userInfo } = await auth.login()\n * ```\n */\nexport class StarchildAuth {\n  // ── Configuration ──────────────────────────────────────────────────────────\n  private readonly _clientId: string\n  private readonly _origin: string\n  private readonly _apiBase: string\n  private readonly _chatApiBase: string\n  private readonly _popupWidth: number\n  private readonly _popupHeight: number\n  private readonly _refreshInterval: number\n\n  // ── Callbacks ──────────────────────────────────────────────────────────────\n  private readonly _onLogin: ((result: LoginResult) => void) | null\n  private readonly _onLogout: (() => void) | null\n  private readonly _onTokenRefresh: ((accessToken: string) => void) | null\n  private readonly _onTokenRefreshFailed: (() => void) | null\n\n  // ── State ──────────────────────────────────────────────────────────────────\n  private _accessToken: string | null = null\n  private _refreshToken: string | null = null\n  private _userInfo: UserInfo | null = null\n  private _destroyed = false\n\n  // ── Pending operations ─────────────────────────────────────────────────────\n  private _pendingLogin: PendingLogin | null = null\n\n  // ── Timers ─────────────────────────────────────────────────────────────────\n  private _refreshTimer: ReturnType<typeof setInterval> | null = null\n  private _popupPollTimer: ReturnType<typeof setInterval> | null = null\n\n  // ── Bound handlers ─────────────────────────────────────────────────────────\n  private readonly _handleMessage: (event: MessageEvent) => void\n  private readonly _handleVisibility: () => void\n\n  constructor(options: StarchildAuthOptions) {\n    if (!options?.clientId) {\n      throw new Error('StarchildAuth: clientId is required. Obtain one from the Starchild Developer Console.')\n    }\n\n    this._clientId = options.clientId\n    this._origin = options.origin ?? DEFAULT_ORIGIN\n    this._apiBase = options.apiBase ?? DEFAULT_API_BASE\n    this._chatApiBase = options.chatApiBase ?? DEFAULT_CHAT_API_BASE\n    this._popupWidth = options.popupWidth ?? DEFAULT_POPUP_WIDTH\n    this._popupHeight = options.popupHeight ?? DEFAULT_POPUP_HEIGHT\n    this._refreshInterval = options.refreshInterval ?? DEFAULT_REFRESH_INTERVAL\n\n    this._onLogin = options.onLogin ?? null\n    this._onLogout = options.onLogout ?? null\n    this._onTokenRefresh = options.onTokenRefresh ?? null\n    this._onTokenRefreshFailed = options.onTokenRefreshFailed ?? null\n\n    // Bind event handlers\n    this._handleMessage = this._onMessage.bind(this)\n    this._handleVisibility = this._onVisibilityChange.bind(this)\n\n    window.addEventListener('message', this._handleMessage)\n    document.addEventListener('visibilitychange', this._handleVisibility)\n\n    // Auto-login: attempt to restore session from stored refreshToken\n    if (options.autoLogin !== false) {\n      this._tryAutoLogin()\n    }\n  }\n\n  // ═══════════════════════════════════════════════════════════════════════════\n  // Public API\n  // ═══════════════════════════════════════════════════════════════════════════\n\n  /**\n   * Open a popup window for the user to sign in with Starchild.\n   *\n   * If the user already has a valid session, the popup will auto-complete\n   * and close almost instantly (similar to Google One Tap).\n   *\n   * @returns Promise resolving with `{ accessToken, refreshToken, expiresIn, userInfo }`\n   * @throws If the popup is blocked or the user closes it before completing login\n   */\n  login(): Promise<LoginResult> {\n    if (this._destroyed) {\n      return Promise.reject(new Error('StarchildAuth instance has been destroyed'))\n    }\n\n    return new Promise<LoginResult>((resolve, reject) => {\n      const state = generateNonce()\n      this._pendingLogin = { resolve, reject, state }\n\n      const url =\n        `${this._origin}/auth-popup` +\n        `?client_id=${encodeURIComponent(this._clientId)}` +\n        `&origin=${encodeURIComponent(window.location.origin)}` +\n        `&state=${encodeURIComponent(state)}` +\n        `&scope=profile`\n\n      const features = popupFeatures(this._popupWidth, this._popupHeight)\n      const popup = window.open(url, 'starchild_auth_popup', features)\n\n      if (!popup || popup.closed) {\n        this._pendingLogin = null\n        reject(new Error('Popup was blocked by the browser. Please allow popups for this site.'))\n        return\n      }\n\n      // Poll to detect if user closes the popup without completing login\n      this._popupPollTimer = setInterval(() => {\n        try {\n          if (!popup || popup.closed) {\n            this._clearPopupPoll()\n            if (this._pendingLogin) {\n              const pending = this._pendingLogin\n              this._pendingLogin = null\n              pending.reject(new Error('Login popup was closed before completing sign-in.'))\n            }\n          }\n        } catch {\n          // Cross-origin access error — popup is still open, ignore\n        }\n      }, 500)\n    })\n  }\n\n  /**\n   * Log out: clear tokens, stop refresh timer, revoke refresh token via API.\n   *\n   * @returns Promise that resolves when logout is complete\n   */\n  async logout(): Promise<void> {\n    if (this._destroyed) {\n      return Promise.reject(new Error('StarchildAuth instance has been destroyed'))\n    }\n\n    try {\n      if (this._refreshToken) {\n        await fetch(`${this._apiBase}/oauth/logout`, {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({\n            client_id: this._clientId,\n            refresh_token: this._refreshToken,\n          }),\n        })\n      }\n    } catch {\n      // logout API failure should not block local cleanup\n    }\n\n    // Clear local storage\n    localStorage.removeItem(`starchild_rt_${this._clientId}`)\n    this._accessToken = null\n    this._refreshToken = null\n    this._userInfo = null\n    this._stopAutoRefresh()\n\n    this._safeCall(this._onLogout)\n  }\n\n  /**\n   * Get the current access token.\n   * Returns `null` if the user is not logged in.\n   */\n  getToken(): string | null {\n    return this._accessToken\n  }\n\n  /**\n   * Get the current user info.\n   * Returns `null` if the user is not logged in.\n   */\n  getUserInfo(): UserInfo | null {\n    return this._userInfo\n  }\n\n  /**\n   * Check if the user is currently logged in (has a valid access token).\n   */\n  isLoggedIn(): boolean {\n    return this._accessToken !== null\n  }\n\n  /**\n   * Manually trigger a token refresh via API.\n   *\n   * Normally tokens are refreshed automatically every 12 minutes.\n   * Use this if you need a fresh token immediately.\n   *\n   * @returns Promise resolving with the new access token\n   * @throws If the refresh fails (session expired or no refresh token)\n   */\n  async refreshToken(): Promise<string> {\n    if (this._destroyed) {\n      throw new Error('StarchildAuth instance has been destroyed')\n    }\n\n    if (!this._refreshToken) {\n      throw new Error('No refresh token available. User must login first.')\n    }\n\n    const token = await this._doRefreshApi()\n    return token\n  }\n\n  /**\n   * Destroy the instance: remove event listeners, clear timers, clear tokens.\n   *\n   * After calling `destroy()`, the instance cannot be used again.\n   * Create a new `StarchildAuth` instance if needed.\n   */\n  destroy(): void {\n    this._destroyed = true\n    this._accessToken = null\n    this._refreshToken = null\n    this._userInfo = null\n    this._pendingLogin = null\n\n    window.removeEventListener('message', this._handleMessage)\n    document.removeEventListener('visibilitychange', this._handleVisibility)\n\n    this._stopAutoRefresh()\n    this._clearPopupPoll()\n  }\n\n  // ═══════════════════════════════════════════════════════════════════════════\n  // Internal — message handling\n  // ═══════════════════════════════════════════════════════════════════════════\n\n  /** Handle incoming postMessage events from Starchild pages. */\n  private _onMessage(event: MessageEvent): void {\n    // Security: only accept messages from the configured Starchild origin\n    if (event.origin !== this._origin) return\n\n    const data = event.data as StarchildMessage | undefined\n    if (!data || typeof data.type !== 'string') return\n\n    switch (data.type) {\n      case 'starchild_auth_success':\n        this._handleAuthSuccess(data)\n        break\n      case 'starchild_auth_error':\n        this._handleAuthError(data.error, data.message)\n        break\n      case 'starchild_auth_cancelled':\n        this._handleAuthCancelled()\n        break\n    }\n  }\n\n  /** Handle successful login from the popup. */\n  private _handleAuthSuccess(data: AuthSuccessMessage): void {\n    // Validate state to prevent CSRF\n    if (this._pendingLogin && data.state !== this._pendingLogin.state) {\n      return // State mismatch — ignore (possible CSRF attempt)\n    }\n\n    this._accessToken = data.accessToken\n    this._refreshToken = data.refreshToken\n    this._userInfo = data.userInfo ?? null\n\n    // Persist refreshToken to localStorage for session restoration\n    localStorage.setItem(`starchild_rt_${this._clientId}`, data.refreshToken)\n\n    this._clearPopupPoll()\n    this._startAutoRefresh()\n\n    const result: LoginResult = {\n      accessToken: this._accessToken,\n      refreshToken: this._refreshToken,\n      expiresIn: data.expiresIn,\n      userInfo: this._userInfo!,\n    }\n\n    // Resolve the login promise\n    if (this._pendingLogin) {\n      const pending = this._pendingLogin\n      this._pendingLogin = null\n      pending.resolve(result)\n    }\n\n    // Fire callback\n    this._safeCall(this._onLogin, result)\n  }\n\n  /** Handle auth error from the popup. */\n  private _handleAuthError(error: string, message: string): void {\n    this._clearPopupPoll()\n\n    if (this._pendingLogin) {\n      const pending = this._pendingLogin\n      this._pendingLogin = null\n      pending.reject(new Error(`Auth error [${error}]: ${message}`))\n    }\n  }\n\n  /** Handle auth cancelled (user closed popup via cancel button). */\n  private _handleAuthCancelled(): void {\n    this._clearPopupPoll()\n\n    if (this._pendingLogin) {\n      const pending = this._pendingLogin\n      this._pendingLogin = null\n      pending.reject(new Error('Login was cancelled by the user.'))\n    }\n  }\n\n  /** Handle token refresh failure. */\n  private _handleTokenRefreshFailed(): void {\n    // Stop auto-refresh — user needs to login again\n    this._stopAutoRefresh()\n\n    // Clear stored refresh token since it's no longer valid\n    localStorage.removeItem(`starchild_rt_${this._clientId}`)\n    this._refreshToken = null\n\n    // Fire callback\n    this._safeCall(this._onTokenRefreshFailed)\n  }\n\n  // ═══════════════════════════════════════════════════════════════════════════\n  // Internal — refresh & timers\n  // ═══════════════════════════════════════════════════════════════════════════\n\n  /** Try to restore session from stored refreshToken in localStorage. */\n  private _tryAutoLogin(): void {\n    const stored = localStorage.getItem(`starchild_rt_${this._clientId}`)\n    if (stored) {\n      this._refreshToken = stored\n      this._doRefresh()\n    }\n  }\n\n  /** Perform a token refresh via API (fire-and-forget for auto-refresh). */\n  private async _doRefresh(): Promise<void> {\n    if (this._destroyed || !this._refreshToken) return\n\n    try {\n      await this._doRefreshApi()\n    } catch {\n      this._handleTokenRefreshFailed()\n    }\n  }\n\n  /**\n   * Call the refresh API and return the new access token.\n   * Throws on failure.\n   */\n  private async _doRefreshApi(): Promise<string> {\n    const resp = await fetch(`${this._apiBase}/oauth/refresh`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        client_id: this._clientId,\n        refresh_token: this._refreshToken,\n      }),\n    })\n\n    if (!resp.ok) {\n      throw new Error('Token refresh failed')\n    }\n\n    const data = await resp.json()\n    this._accessToken = data.access_token\n\n    // Start auto-refresh if not already running\n    if (!this._refreshTimer) {\n      this._startAutoRefresh()\n    }\n\n    // Fire token refresh callback\n    this._safeCall(this._onTokenRefresh, data.access_token)\n\n    // Fetch user info using the new access token\n    const userInfo = await this._fetchUserInfo()\n    if (userInfo) {\n      this._userInfo = userInfo\n      // Fire onLogin so the UI can update with user info\n      this._safeCall(this._onLogin, {\n        accessToken: this._accessToken!,\n        refreshToken: this._refreshToken!,\n        expiresIn: data.expires_in ?? 0,\n        userInfo: this._userInfo,\n      })\n    }\n\n    return data.access_token\n  }\n\n  /**\n   * Fetch user info from /oauth/userinfo using the current access token.\n   */\n  private async _fetchUserInfo(): Promise<UserInfo | null> {\n    if (!this._accessToken) return null\n    try {\n      const resp = await fetch(`${this._chatApiBase}/v1/oauth/userinfo`, {\n        method: 'GET',\n        headers: {\n          Authorization: `Bearer ${this._accessToken}`,\n        },\n      })\n      if (!resp.ok) return null\n      const data = await resp.json()\n      return {\n        userInfoId: data.userInfoId ?? data.user_info_id ?? '',\n        agentName: data.agentName ?? data.agent_name ?? data.user_name ?? '',\n        agentAvatar: data.agentAvatar ?? data.agent_avatar ?? data.avatar ?? '',\n      }\n    } catch {\n      return null\n    }\n  }\n\n  /** Start the periodic auto-refresh timer. */\n  private _startAutoRefresh(): void {\n    this._stopAutoRefresh()\n    this._refreshTimer = setInterval(() => {\n      this._doRefresh()\n    }, this._refreshInterval)\n  }\n\n  /** Stop the periodic auto-refresh timer. */\n  private _stopAutoRefresh(): void {\n    if (this._refreshTimer) {\n      clearInterval(this._refreshTimer)\n      this._refreshTimer = null\n    }\n  }\n\n  /** Clear the popup close-detection poll timer. */\n  private _clearPopupPoll(): void {\n    if (this._popupPollTimer) {\n      clearInterval(this._popupPollTimer)\n      this._popupPollTimer = null\n    }\n  }\n\n  /** Handle visibility change: refresh token when page comes back from background. */\n  private _onVisibilityChange(): void {\n    if (document.visibilityState === 'visible' && this._accessToken && !this._destroyed) {\n      this._doRefresh()\n    }\n  }\n\n  // ═══════════════════════════════════════════════════════════════════════════\n  // Internal — helpers\n  // ═══════════════════════════════════════════════════════════════════════════\n\n  /** Safely call a callback, catching and logging any errors. */\n  private _safeCall<T extends unknown[]>(fn: ((...args: T) => void) | null, ...args: T): void {\n    if (!fn) return\n    try {\n      fn(...args)\n    } catch (e) {\n      console.error('[StarchildAuth] Callback error:', e)\n    }\n  }\n}\n"],"names":["generateNonce","arr","b","popupFeatures","width","height","left","top","DEFAULT_ORIGIN","DEFAULT_API_BASE","DEFAULT_CHAT_API_BASE","DEFAULT_POPUP_WIDTH","DEFAULT_POPUP_HEIGHT","DEFAULT_REFRESH_INTERVAL","StarchildAuth","options","resolve","reject","state","url","features","popup","pending","event","data","result","error","message","stored","resp","userInfo","fn","args","e"],"mappings":"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"}