import { OAuth2Tokens, RestApiClient } from '@docyrus/api-client'; import { D as DocyrusAuthConfig, c as AuthMode, e as AuthStatus, o as DocyrusUser, G as GuidyRoute, R as RouteChangePayload, w as HostNavigationRequestOptions, m as DocyrusSharePayload, i as DocyrusEmailPayload, h as DocyrusCalendarEventPayload, p as MsGraphClient, H as HostNavigationHandler, v as HostNotificationHandler, k as DocyrusRole, u as PermissionScope, P as PermissionConfig } from './types-BcLDyMdw.js'; type AuthStateListener = (state: { status: AuthStatus; tokens: OAuth2Tokens | null; error: Error | null; user: DocyrusUser | null; }) => void; /** * Unified authentication manager. * Orchestrates standalone OAuth2 and iframe postMessage modes, * exposes a pre-configured RestApiClient, and manages token lifecycle. */ declare class AuthManager { private mode; private status; private tokens; private error; private client; private user; private standaloneAuth; private iframeAuth; private guidyBridge; private msGraphClient; private reactNativeAuth; private tokenRefreshTimer; /** Shared in-flight refresh, so concurrent requests don't trigger parallel refreshes. */ private refreshInFlight; private listeners; private navigationHandlers; private notificationHandlers; private config; constructor(config?: DocyrusAuthConfig); /** Whether the provider may refresh tokens on its own. Default: true. */ private get autoRefreshEnabled(); getMode(): AuthMode; getStatus(): AuthStatus; getTokens(): OAuth2Tokens | null; getClient(): RestApiClient | null; getError(): Error | null; getUser(): DocyrusUser | null; /** Re-fetch the current user from the API. No-op if not authenticated. */ refreshUser(): Promise; subscribe(listener: AuthStateListener): () => void; private notify; private getInitialTokens; /** Initialize the auth manager. Must be called once on mount. */ initialize(): Promise; /** * Standalone mode initialization. * 1. Check if we're returning from an OAuth callback. * 2. If not, check for existing tokens in localStorage. * 3. If tokens are expired, try to refresh. */ private initializeStandaloneMode; /** * Iframe mode initialization. * Listen for postMessage tokens from the host. * Status remains 'loading' until the host sends the first signin message. */ private initializeIframeMode; /** * Start the Guidy bridge runtime: report the app's clickable inventory to * the host and execute host scan/point/click commands. Iframe mode only. */ private startGuidyBridge; /** * Iframe mode: replace the routes the Guidy bridge advertises to the host. * No-op unless the bridge is running (`enableGuidyBridge`). */ setGuidyRoutes(routes: GuidyRoute[]): void; /** * Iframe/WebView mode: start auto-syncing the embedded app's route * to the host. Patches history methods and listens for popstate / * hashchange. Idempotent. No-op outside iframe mode. */ enableHostRouteSync(): void; /** * Iframe/WebView mode: post a single `route-change` message to the * host. With no argument, reads `window.location`. Pass a payload * from a router subscription to report a known route. No-op outside * iframe mode. */ notifyHostRouteChange(payload?: RouteChangePayload): void; /** * Iframe/WebView mode: ask the host shell to navigate to a path/URL. * Posts a `navigation-request` message; the host decides how to honour it. * No-op outside iframe mode. */ requestHostNavigation(url: string, options?: HostNavigationRequestOptions): void; /** * Iframe/WebView mode: hand a payload to the host AI assistant (Docy). * Resolves when the host acknowledges delivery. Rejects outside iframe mode. */ sendToDocy(payload: DocyrusSharePayload): Promise; /** * Iframe/WebView mode: hand a payload to the host team-chat app. * Resolves when the host acknowledges delivery. Rejects outside iframe mode. */ sendToChat(payload: DocyrusSharePayload): Promise; /** * Iframe/WebView mode: hand a draft email to the host. Resolves when the * host acknowledges. Rejects outside iframe mode. */ sendToEmail(payload: DocyrusEmailPayload): Promise; /** * Iframe/WebView mode: hand a calendar event to the host. Resolves when the * host acknowledges. Rejects outside iframe mode. */ sendToCalendar(payload: DocyrusCalendarEventPayload): Promise; /** * Iframe/WebView mode: get the client for the host's Microsoft Graph (MSAL) * session. Returns `null` outside iframe mode. */ getMsGraphClient(): MsGraphClient | null; /** * Subscribe to host `navigation` messages. Returns an unsubscribe function. * Handlers registered before iframe mode is initialized are retained and * will fire once messages arrive. No-op in non-iframe modes. */ onHostNavigation(handler: HostNavigationHandler): () => void; /** * Subscribe to host `notification` messages. Returns an unsubscribe function. * Handlers registered before iframe mode is initialized are retained and * will fire once messages arrive. No-op in non-iframe modes. */ onHostNotification(handler: HostNotificationHandler): () => void; /** * React Native mode initialization. * No callback URL check needed — the in-app browser returns the URL directly. * Just check for existing tokens and refresh if expired. */ private initializeReactNativeMode; /** Initiate sign-in. Works in standalone and react-native modes. */ signIn(): Promise; /** * Bootstrap an authenticated session from tokens obtained outside the * browser redirect flow, such as a prior device authorization flow. */ signInWithTokens(tokens: OAuth2Tokens): Promise; /** * Get the OAuth2 authorization URL without navigating. * Use this in Electron apps to open the URL in an external browser. * Returns null if not in standalone mode. */ getAuthorizationUrl(): Promise; /** * Sign out. * Standalone: revoke token, clear localStorage, reset state. * Iframe: clear local state (host manages the actual session). */ signOut(): Promise; /** * Called when valid tokens are received (either mode). * Creates/updates the RestApiClient and schedules token refresh. * Fires a user fetch in the background — the first notify() fires with user: null, * and a second notify() fires once the user is fetched. */ private setAuthenticated; /** Fetch the current user from /v1/users/me. Silently sets user to null on failure. */ private fetchUser; /** * Create a RestApiClient with a custom TokenManager that proactively * refreshes the token in getToken(). This is necessary because * BaseApiClient.getAccessToken() only calls tokenManager.getToken() * and does NOT auto-call refreshToken() when the token is expired. */ private createClient; /** * Get a valid access token, proactively refreshing if expired. * Called by the RestApiClient on every request via tokenManager.getToken(). */ private getValidToken; /** * Handle token refresh depending on mode, sharing a single in-flight * request across concurrent callers. Multiple requests crossing the expiry * buffer at once (e.g. a dashboard firing several queries) would otherwise * each trigger their own refresh; with refresh-token rotation only the first * succeeds and the rest can leave us holding an expired token — exactly the * backend "JWTExpired" the proactive path is meant to prevent. */ private handleTokenRefresh; /** * Refresh depending on mode. * Standalone: use OAuth2Client.getValidAccessToken() which auto-refreshes. * Iframe: send postMessage to host requesting new tokens. */ private performTokenRefresh; /** Schedule proactive token refresh before expiry. */ private scheduleTokenRefresh; private clearTokenRefreshTimer; /** * Resolve token expiry from stored expiresAt, falling back to the JWT exp * claim when expiresAt is absent (e.g. server omitted expires_in). */ private resolveExpiry; /** Cleanup: remove listeners, timers, stop iframe auth. */ destroy(): void; } /** * Get all roles for a user (primaryRole + roles array), deduplicated by uid. */ declare function getAllRoles(user: DocyrusUser | null | undefined): DocyrusRole[]; /** * Check if the user has a specific role. * * - If `role` is null/undefined, returns true (no role requirement). * - Checks both primaryRole and roles array. * - Matches by slug or uid. */ declare function hasRole(user: DocyrusUser | null | undefined, role: string | string[] | null | undefined): boolean; /** * Every operation the user is granted within a scope, merged across roles. * * Omit `scope` (or pass one with no ids) for tenant-wide operations; pass a * data source id, or a {@link PermissionScope} for app / AI tool targets. * * Role shortcuts are deliberately excluded — this reports what the user's rules * actually carry. Use {@link hasPermission} for an access decision. */ declare function getAllowedOperations(user: DocyrusUser | null | undefined, scope?: string | null | PermissionScope): string[]; /** * Check if the user has permission for an operation. * * `scope` accepts a data source id, a {@link PermissionScope} for app / AI tool * targets, or nothing at all for tenant-wide operations such as `ai-access`, * `manage_users` or `studio`. * * Permission resolution order: * 1. super_admin role → always true * 2. global_editor role + dataSourceId → true if operation is in the global_editor set * 3. global_viewer role + dataSourceId → true only for 'view' * 4. Always-permitted data sources (configurable) * 5. The user's permissions for the scope (`permissions`, falling back to `aclRules`) */ declare function hasPermission(user: DocyrusUser | null | undefined, operation: string, scope?: string | null | PermissionScope, config?: PermissionConfig): boolean; declare const DEFAULT_API_URL = "https://alpha-api.docyrus.com"; declare const DEFAULT_OAUTH_SCOPES: string[]; declare const DEFAULT_CALLBACK_PATH = "/auth/callback"; /** Default cookie name for SSR token sync */ declare const DEFAULT_SSR_COOKIE_KEY = "docyrus-token"; export { AuthManager as A, DEFAULT_API_URL as D, DEFAULT_OAUTH_SCOPES as a, getAllowedOperations as b, hasRole as c, DEFAULT_CALLBACK_PATH as d, DEFAULT_SSR_COOKIE_KEY as e, type AuthStateListener as f, getAllRoles as g, hasPermission as h };