import { OAuth2Tokens, OAuth2TokenStorage, CryptoProvider, RestApiClient } from '@docyrus/api-client'; type IframeAuthCallback = (tokens: OAuth2Tokens) => void; /** * Iframe / WebView authentication via postMessage. * * Protocol: * - App → Host: { type: "signin-ready" } (on start) * - Host → App: { type: "signin", accessToken, refreshToken } * - App → Host: { type: "token-refresh-request" } * - Host → App: { type: "navigation", url } * - Host → App: { type: "notification", notification } * - App → Host: { type: "route-change", path, search, hash, url } * - App → Host: { type: "navigation-request", url, replace?, newTab? } * * Every incoming message's event.origin is validated against * the allowed host pattern before processing. * In WebView mode, origin validation is skipped (ReactNativeWebView bridge). */ declare class IframeAuth { private allowedOrigins; private allowedPattern; private isWebView; private onTokensReceived; private navigationHandlers; private notificationHandlers; private guidyHandlers; private routeSyncEnabled; private originalPushState; private originalReplaceState; private routeChangeListener; private stopped; private refreshPromise; private messageHandler; /** * In-flight app→host requests awaiting a correlated host reply, keyed by * requestId. Powers Send to Docy / Send to Chat / the MS Graph bridge. */ private pendingRequests; /** Fallback monotonic counter for request ids when crypto.randomUUID is absent. */ private requestCounter; constructor(allowedOrigins?: string[], allowedPattern?: RegExp); /** * Start listening for postMessage events from the host. * The callback is invoked every time valid tokens are received. */ start(onTokensReceived: IframeAuthCallback): void; /** Stop listening for postMessage events. */ stop(): void; /** * Patch history methods + listen for popstate/hashchange so every * route change posts a `route-change` message to the host. * Idempotent. Fires an immediate message with the current route. */ enableRouteSync(): void; /** * Post a single `route-change` message. With no argument, reads * `window.location`. Pass a payload from a router subscription to * report a known route instead. */ notifyRouteChange(payload?: RouteChangePayload): void; /** * Ask the host shell to navigate to a path/URL. The reverse of the * host → app `navigation` message: posts a `navigation-request` over the * same validated channel. The host decides how to honour it. */ requestHostNavigation(url: string, options?: HostNavigationRequestOptions): void; private teardownRouteSync; /** * Subscribe to host navigation messages. * Returns an unsubscribe function. */ onNavigation(handler: HostNavigationHandler): () => void; /** * Subscribe to host notification messages. * Returns an unsubscribe function. */ onNotification(handler: HostNotificationHandler): () => void; /** * Subscribe to host `guidy:*` command messages (point/scan). * Returns an unsubscribe function. Used by the Guidy bridge runtime. */ onGuidyCommand(handler: GuidyCommandHandler): () => void; /** * Post an app → host message over the same validated channel used for * route-change and token-refresh. Used by the Guidy bridge to push its * element inventory and point acknowledgements. */ sendToHost(message: AppToHostMessage): void; /** * Hand a payload to the host AI assistant (Docy). Resolves when the host * acknowledges delivery, rejects on host error or timeout. */ sendToDocy(payload: DocyrusSharePayload): Promise; /** * Hand a payload to the host team-chat app. Resolves when the host * acknowledges delivery, rejects on host error or timeout. */ sendToChat(payload: DocyrusSharePayload): Promise; /** * Hand a draft email to the host. Resolves when the host acknowledges, * rejects on host error or timeout. */ sendToEmail(payload: DocyrusEmailPayload): Promise; /** * Hand a calendar event to the host. Resolves when the host acknowledges, * rejects on host error or timeout. */ sendToCalendar(payload: DocyrusCalendarEventPayload): Promise; /** Ask the host whether its MSAL session is signed in. */ requestMsGraphStatus(): Promise; /** Perform a Microsoft Graph request through the host's MSAL session. */ requestMsGraph(request: MsGraphRequest): Promise; /** * Post a correlated app→host request and await the matching host reply. * The reply is matched by `requestId` in `handleMessage`. Rejects on timeout * or when the bridge is stopped. */ private request; /** Generate a correlation id, preferring crypto.randomUUID when available. */ private nextRequestId; private resolvePendingRequest; private rejectPendingRequest; private rejectAllPendingRequests; /** * Request fresh tokens from the host. * Posts a "token-refresh-request" to the host, then waits for * a "signin" response. * * Only one refresh request can be in-flight at a time. * Additional callers share the same promise. */ requestTokenRefresh(): Promise; private isOriginAllowed; private handleMessage; private handleActionAck; private handleMsGraphStatusResponse; private handleMsGraphResponse; private handleGuidyCommand; private handleSignin; private handleNavigation; private handleNotification; private rejectPendingRefresh; } /** Extra per-call options for the ergonomic Graph helpers. */ interface MsGraphRequestOptions { /** Extra request headers (the host may filter these). */ headers?: Record; /** Optional scopes hint for the token the host should acquire. */ scopes?: string[]; } /** * A client for the host's Microsoft Graph (MSAL) session, usable from an * embedded app. Every call is **proxied** through the host: the host acquires * the token via MSAL, performs the Graph request, and returns only the * response. The MSAL access token never crosses the frame boundary. * * Obtain one via `useDocyrusMsGraph()` (React), `getDocyrusAuth().msGraph` * (Vue), or `AuthManager.getMsGraphClient()`. Only available in iframe/WebView * mode — it is `null` elsewhere. */ declare class MsGraphClient { private iframeAuth; constructor(iframeAuth: IframeAuth); /** Whether the host's MSAL session is signed in, plus optional account info. */ status(): Promise; /** Convenience: resolves to whether the host's MSAL session is signed in. */ isSignedIn(): Promise; /** Perform an arbitrary Microsoft Graph request via the host's MSAL session. */ request(request: MsGraphRequest): Promise; /** GET a Graph resource, e.g. `get('/me/messages?$top=5')`. */ get(path: string, options?: MsGraphRequestOptions): Promise; /** POST a JSON body to a Graph resource. */ post(path: string, body?: unknown, options?: MsGraphRequestOptions): Promise; /** PATCH a JSON body to a Graph resource. */ patch(path: string, body?: unknown, options?: MsGraphRequestOptions): Promise; /** PUT a JSON body to a Graph resource. */ put(path: string, body?: unknown, options?: MsGraphRequestOptions): Promise; /** DELETE a Graph resource. */ delete(path: string, options?: MsGraphRequestOptions): Promise; /** Convenience: GET `/me` — the signed-in user's profile. */ getMe(): Promise; } /** Authentication mode detected at runtime */ type AuthMode = 'standalone' | 'iframe' | 'react-native'; /** Result from the native auth session (e.g., expo-web-browser) */ interface AuthSessionResult { type: string; url?: string; } /** Function signature for opening an auth session in a native browser */ type OpenAuthSessionFn = (url: string, redirectUri: string) => Promise; /** Authentication state exposed to consumers */ type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated'; /** Configuration for the DocyrusAuthProvider */ interface DocyrusAuthConfig { /** OAuth2 client ID. Defaults to the Docyrus public client ID */ clientId?: string; /** API base URL. Defaults to https://alpha-api.docyrus.com */ apiUrl?: string; /** OAuth2 scopes. Defaults to offline_access Read.All Users.Read Users.Read.All DS.Read.All */ scopes?: string[]; /** The redirect URI for OAuth2 callback. Defaults to `${window.location.origin}/auth/callback` */ redirectUri?: string; /** The path where the OAuth2 callback is handled. Defaults to '/auth/callback' */ callbackPath?: string; /** Allowed host origins for iframe mode. Used alongside the default *.docyrus.app pattern */ allowedHostOrigins?: string[]; /** localStorage key prefix for token storage. Defaults to 'docyrus_oauth2' */ storageKeyPrefix?: string; /** Custom token storage implementation (e.g., Electron IPC storage). Overrides storageKeyPrefix */ tokenStorage?: OAuth2TokenStorage; /** Override auto-detection: force a specific auth mode */ forceMode?: AuthMode; /** * Bootstrap an authenticated session from tokens obtained elsewhere * (for example, a prior device flow). When provided, these tokens * replace any currently stored standalone/react-native session. */ initialTokens?: OAuth2Tokens; /** * Automatically refresh the access token before/at expiry. Default: true. * * When `false`, the provider never refreshes tokens on its own — it * disables the proactive pre-expiry timer, the pre-request refresh in * the API client's token getter, and the reactive 401 refresh. The * current access token is used as-is until replaced via * `signInWithTokens`. Use this when an external system owns the token * lifecycle (e.g. a Supabase session whose refresh token is not a valid * Docyrus OAuth2 grant) and pushes fresh tokens in through * `signInWithTokens`. */ autoRefresh?: boolean; /** Enable SSR: sync access token to a cookie readable by server components. Default: false */ ssr?: boolean; /** Cookie name for SSR token sync. Default: 'docyrus-token' */ ssrCookieKey?: string; /** * Iframe/WebView mode: post a `route-change` message to the host on * every history change so the host can reflect the embedded app's * route in its address bar. Patches `history.pushState/replaceState` * and listens for `popstate`/`hashchange`. No-op outside iframe mode. * Default: false. */ syncRouteToHost?: boolean; /** * Iframe mode: let the host assistant (Guidy) inspect and drive this app's * visible UI — scan its clickable elements, highlight/annotate them, and * click them on the user's behalf — over the existing postMessage channel. * * Opt-in: the app must consent to being driven. The bridge only exposes * already-visible interactive elements and only runs a fixed command * vocabulary (scan / point / click); no arbitrary script is accepted from * the host. No-op outside iframe mode. Default: false. */ enableGuidyBridge?: boolean; /** * Iframe mode: routes the host assistant (Guidy) may navigate the user to * inside this app. The host turns each into a deep link it can drive via the * existing host→app `navigation` message. Update at runtime with * `setGuidyRoutes` (e.g. when routes depend on permissions). Requires * `enableGuidyBridge`. Default: none. */ guidyRoutes?: GuidyRoute[]; /** React Native: custom URI scheme redirect (e.g., 'myapp://auth/callback'). Required when forceMode is 'react-native' */ nativeRedirectUri?: string; /** React Native: function to open an in-app browser auth session (e.g., WebBrowser.openAuthSessionAsync from expo-web-browser) */ openAuthSession?: OpenAuthSessionFn; /** Custom crypto provider for PKCE operations in non-browser environments (e.g., ReactNativeCryptoProvider from @docyrus/api-client/react-native) */ cryptoProvider?: CryptoProvider; } /** The shape of the React context value */ interface DocyrusAuthContextValue { /** Current auth state */ status: AuthStatus; /** The detected authentication mode */ mode: AuthMode | null; /** Pre-configured RestApiClient with valid tokens */ client: RestApiClient | null; /** Current tokens (null when unauthenticated) */ tokens: OAuth2Tokens | null; /** Current user data (null when not authenticated or not yet fetched) */ user: DocyrusUser | null; /** Initiate sign-in (only relevant in standalone mode) */ signIn: () => void; /** Bootstrap an authenticated session from existing tokens */ signInWithTokens: (tokens: OAuth2Tokens) => Promise; /** Get the OAuth2 authorization URL without navigating. For Electron apps */ getAuthorizationUrl: () => Promise; /** Sign out and clear tokens */ signOut: () => Promise; /** Check if the current user has a specific role (by slug or uid) */ hasRole: (role: string | string[] | null | undefined) => boolean; /** * Check if the current user has permission for an operation. Pass a data * source id (or a {@link PermissionScope}) to scope it to an entity; omit it * for tenant-wide operations such as `ai-access`. */ hasPermission: (operation: string, scope?: string | null | PermissionScope) => boolean; /** Re-fetch the current user from the API */ refreshUser: () => Promise; /** * Subscribe to host `navigation` messages (iframe/WebView mode only). * Returns an unsubscribe function. No-op in non-iframe modes. */ onHostNavigation: (handler: HostNavigationHandler) => () => void; /** * Subscribe to host `notification` messages (iframe/WebView mode only). * Returns an unsubscribe function. No-op in non-iframe modes. */ onHostNotification: (handler: HostNotificationHandler) => () => void; /** * Iframe/WebView mode: start auto-syncing the embedded app's route * to the host. Patches `history.pushState/replaceState` and listens * for `popstate`/`hashchange`. Safe to call multiple times. No-op in * non-iframe modes. */ enableHostRouteSync: () => void; /** * Iframe/WebView mode: post a single `route-change` message to the host. * When called with no argument, the current `window.location` is read. * Pass a payload to report a specific route (useful with router * subscriptions). No-op in non-iframe modes. */ notifyRouteChange: (payload?: RouteChangePayload) => void; /** * Iframe/WebView mode: ask the host shell to navigate to a path/URL. * The reverse of `onHostNavigation` — lets an in-app action drive the * host's own routing (deep link, switch view, open a sibling app). The * host decides how to honour the request. No-op in non-iframe modes. */ requestHostNavigation: (url: string, options?: HostNavigationRequestOptions) => void; /** * Iframe mode (Guidy bridge): replace the routes the host assistant may * navigate the user to inside this app. No-op unless `enableGuidyBridge` * is set. Use for routes that depend on runtime state (e.g. permissions). */ setGuidyRoutes: (routes: GuidyRoute[]) => void; /** * Iframe/WebView mode: hand a payload to the host AI assistant (Docy). * Resolves when the host acknowledges delivery; rejects on host error or * timeout. Rejects immediately 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 on host error or * timeout. Rejects immediately outside iframe mode. */ sendToChat: (payload: DocyrusSharePayload) => Promise; /** * Iframe/WebView mode: hand a draft email (to/subject/body/cc) to the host * to send or compose. Resolves when the host acknowledges; rejects on host * error or timeout. Rejects immediately outside iframe mode. */ sendToEmail: (payload: DocyrusEmailPayload) => Promise; /** * Iframe/WebView mode: hand a calendar event (subject/description/ * participants/start/end) to the host to create. Resolves when the host * acknowledges; rejects on host error or timeout. Rejects immediately * outside iframe mode. */ sendToCalendar: (payload: DocyrusCalendarEventPayload) => Promise; /** * Iframe/WebView mode: a client for the host's Microsoft Graph (MSAL) * session. Check `isSignedIn()` and make host-proxied Graph requests — the * host performs the call and returns the response; the MSAL access token * never crosses the frame boundary. `null` outside iframe mode. */ msGraph: MsGraphClient | null; /** Any error that occurred during auth */ error: Error | null; } /** PostMessage payload: host sends tokens to the embedded app */ interface HostSignInMessage { type: 'signin'; accessToken: string; refreshToken: string; } /** PostMessage payload: app requests fresh tokens from the host */ interface TokenRefreshRequestMessage { type: 'token-refresh-request'; } /** * PostMessage payload: app reports its current route to the host. * Sent on every history change so the host can reflect it in the * browser address bar. */ interface AppRouteChangeMessage { type: 'route-change'; /** location.pathname (e.g. "/customers/123") */ path: string; /** location.search including leading "?" — empty string if none */ search: string; /** location.hash including leading "#" — empty string if none */ hash: string; /** Convenience: `path + search + hash` */ url: string; } /** Payload for manual `notifyRouteChange` calls */ interface RouteChangePayload { path?: string; search?: string; hash?: string; } /** PostMessage payload: host asks the embedded app to navigate to a URL */ interface HostNavigationMessage { type: 'navigation'; url: string; } /** * PostMessage payload: the embedded app asks the host shell to navigate to a * path/URL. The reverse of `HostNavigationMessage` — used when an in-app action * needs to drive the host's own routing (deep link, switch view, open a * sibling app). The host decides how to honour it. Unlike `route-change`, which * passively reports the app's current route, this is an explicit request. */ interface AppNavigationRequestMessage { type: 'navigation-request'; /** Target path or absolute URL for the host shell to navigate to. */ url: string; /** Hint the host to replace the current history entry instead of pushing. */ replace?: boolean; /** Hint the host to open the target in a new tab/window instead of in place. */ newTab?: boolean; } /** Options for `requestHostNavigation` (app → host navigation request). */ interface HostNavigationRequestOptions { /** Hint the host to replace the current history entry instead of pushing. */ replace?: boolean; /** Hint the host to open the target in a new tab/window instead of in place. */ newTab?: boolean; } /** * Notification payload pushed from the host into the embedded app. * Mirrors the NotificationEntity API contract. */ interface DocyrusNotification { id: string; subject: string; message: string; status: string; seen: boolean; created_on: string; notify_on: string; created_by: string; record_owner: string; created_by_id: string; created_by_fullname: string; created_by_photo: string; params?: Record | null; tenant_app_id?: string | null; output_render_template?: Record | null; } /** PostMessage payload: host pushes a notification to the embedded app */ interface HostNotificationMessage { type: 'notification'; notification: DocyrusNotification; } /** * A visible, interactive element the host assistant (Guidy) can target by id. * Mirrors the host-side clickable inventory so the model can reference real * in-app buttons and links the same way it references shell chrome. */ interface GuidyElement { /** Stable DOM id used as the target for `guidy:point`. */ id: string; /** Human-readable label (aria-label, text, or title). */ label: string; /** Element kind, so the model can phrase guidance naturally. */ tag: 'a' | 'button'; } /** * App → Host: the embedded app's current clickable inventory. * Pushed proactively on mount, route change, and DOM mutation so the host * can keep a fresh snapshot without a request round-trip. */ interface GuidyElementsMessage { type: 'guidy:elements'; /** The app's current `location.pathname` when the scan was taken. */ path: string; elements: GuidyElement[]; } /** * A navigable route the host assistant (Guidy) can send the user to. Unlike * elements, routes cannot be auto-discovered from the DOM, so the app declares * them (via `guidyRoutes` / `setGuidyRoutes`). The host turns these into deep * links it can drive through the existing host→app `navigation` message. */ interface GuidyRoute { /** App-internal path, e.g. `/leads` or `leads/new`. */ path: string; /** Human-readable label, e.g. `Leads`. */ label: string; } /** * App → Host: the embedded app's declared navigable routes. * Pushed on start and whenever the app updates its route catalog. */ interface GuidyRoutesMessage { type: 'guidy:routes'; routes: GuidyRoute[]; } /** * Host → App: scroll to, highlight, and optionally annotate/click an element. * The app renders the highlight/annotation itself — the host cannot draw into * a cross-origin iframe. */ interface GuidyPointMessage { type: 'guidy:point'; /** Target element id (must match a `GuidyElement.id`). */ id: string; /** When true, dispatch a click after highlighting. Default: false. */ click?: boolean; /** Optional short message shown in an annotation bubble near the element. */ message?: string; } /** * Host → App: request a fresh element inventory. Used to recover from a late * host mount that missed the app's proactive push. The app replies with a * `guidy:elements` message. */ interface GuidyScanMessage { type: 'guidy:scan'; } /** App → Host: result of a `guidy:point` command. */ interface GuidyPointAckMessage { type: 'guidy:point-ack'; /** The id that was targeted. */ id: string; /** Whether the element was found and acted upon. */ ok: boolean; } /** Host → App: commands the Guidy bridge runtime handles. */ type GuidyCommandMessage = GuidyPointMessage | GuidyScanMessage; /** Handler invoked when the host sends a Guidy command. */ type GuidyCommandHandler = (message: GuidyCommandMessage) => void; /** * A minimal structural type for a raw Adaptive Card document * (schema http://adaptivecards.io/schemas/adaptive-card.json). Kept * dependency-free on purpose — the host renders the card, so the SDK does not * import an Adaptive Card library. Pass the card JSON through as-is. */ interface AdaptiveCard { type: 'AdaptiveCard'; version?: string; body?: unknown[]; actions?: unknown[]; [key: string]: unknown; } /** Plain-text (or markdown) payload handed to a host surface. */ interface DocyrusShareTextPayload { kind: 'text'; /** The text/markdown body. */ text: string; /** Optional short title/subject shown by the host surface. */ title?: string; } /** Adaptive Card payload handed to a host surface. */ interface DocyrusShareAdaptiveCardPayload { kind: 'adaptiveCard'; /** Raw Adaptive Card JSON the host will render. */ card: AdaptiveCard; /** Fallback text for hosts that cannot render the card. */ fallbackText?: string; } /** * The payload an embedded app can hand off to a host surface (Docy or Chat). * Two kinds: plain `text` or an `adaptiveCard`. */ type DocyrusSharePayload = DocyrusShareTextPayload | DocyrusShareAdaptiveCardPayload; /** App → Host: hand a payload to the host AI assistant (Docy). */ interface DocySendMessage { type: 'docy:send'; /** Correlation id — the host echoes it in the matching `docy:send-ack`. */ requestId: string; payload: DocyrusSharePayload; } /** App → Host: hand a payload to the host team-chat app. */ interface ChatSendMessage { type: 'chat:send'; /** Correlation id — the host echoes it in the matching `chat:send-ack`. */ requestId: string; payload: DocyrusSharePayload; } /** Host → App: acknowledgement of a `docy:send`. */ interface DocySendAckMessage { type: 'docy:send-ack'; requestId: string; /** Whether the host accepted and delivered the payload. */ ok: boolean; /** Failure reason when `ok` is false. */ error?: string; } /** Host → App: acknowledgement of a `chat:send`. */ interface ChatSendAckMessage { type: 'chat:send-ack'; requestId: string; /** Whether the host accepted and delivered the payload. */ ok: boolean; /** Failure reason when `ok` is false. */ error?: string; } /** A draft email an embedded app hands to the host to send/compose. */ interface DocyrusEmailPayload { /** Recipient address(es). */ to: string | string[]; /** Subject line. */ subject: string; /** Body (plain text or HTML — the host decides how to render/send). */ body: string; /** Carbon-copy recipient(s). */ cc?: string | string[]; } /** A calendar event an embedded app hands to the host to create. */ interface DocyrusCalendarEventPayload { /** Event title/subject. */ subject: string; /** Event description/body. */ description?: string; /** Participant address(es). */ participants?: string | string[]; /** Event start — ISO 8601 datetime string (e.g. '2026-07-14T09:00:00Z'). */ start: string; /** Event end — ISO 8601 datetime string. */ end: string; } /** App → Host: hand a draft email to the host. */ interface EmailSendMessage { type: 'email:send'; /** Correlation id — the host echoes it in the matching `email:send-ack`. */ requestId: string; payload: DocyrusEmailPayload; } /** App → Host: hand a calendar event to the host. */ interface CalendarSendMessage { type: 'calendar:send'; /** Correlation id — the host echoes it in the matching `calendar:send-ack`. */ requestId: string; payload: DocyrusCalendarEventPayload; } /** Host → App: acknowledgement of an `email:send`. */ interface EmailSendAckMessage { type: 'email:send-ack'; requestId: string; /** Whether the host accepted the email. */ ok: boolean; /** Failure reason when `ok` is false. */ error?: string; } /** Host → App: acknowledgement of a `calendar:send`. */ interface CalendarSendAckMessage { type: 'calendar:send-ack'; requestId: string; /** Whether the host accepted the calendar event. */ ok: boolean; /** Failure reason when `ok` is false. */ error?: string; } /** * A Microsoft Graph request the host performs on the app's behalf using the * host's MSAL session (proxy-only — the access token never crosses the frame * boundary). */ interface MsGraphRequest { /** HTTP method. Default: 'GET'. */ method?: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE'; /** Graph resource path or absolute URL, e.g. '/me' or '/me/messages?$top=5'. */ path: string; /** Extra request headers (the host may filter these). */ headers?: Record; /** JSON body for write operations. */ body?: unknown; /** Optional scopes hint for the token the host should acquire. */ scopes?: string[]; } /** The result of a host-proxied Microsoft Graph call. */ interface MsGraphResponse { /** True when the Graph call returned a 2xx status. */ ok: boolean; /** HTTP status code (0 when the host could not perform the request at all). */ status: number; /** Parsed JSON (or text) response body. */ data?: unknown; /** Error message when the host could not perform the request. */ error?: string; } /** Minimal account info the host chooses to share about the MSAL session. */ interface MsGraphAccount { username?: string; name?: string; tenantId?: string; } /** Whether the host's MSAL session is signed in, plus optional account info. */ interface MsGraphStatus { signedIn: boolean; account?: MsGraphAccount | null; } /** App → Host: is the host's MSAL session signed in? */ interface MsGraphStatusRequestMessage { type: 'msgraph:status-request'; requestId: string; } /** App → Host: perform a Microsoft Graph request via the host's MSAL session. */ interface MsGraphRequestMessage { type: 'msgraph:request'; requestId: string; request: MsGraphRequest; } /** Host → App: MSAL sign-in status reply. */ interface MsGraphStatusResponseMessage { type: 'msgraph:status-response'; requestId: string; signedIn: boolean; account?: MsGraphAccount | null; /** Present when the host could not resolve status. */ error?: string; } /** Host → App: the result of a proxied Microsoft Graph request. */ interface MsGraphResponseMessage { type: 'msgraph:response'; requestId: string; ok: boolean; status: number; data?: unknown; /** Present when the host could not perform the request (transport-level). */ error?: string; } type AppToHostMessage = TokenRefreshRequestMessage | AppRouteChangeMessage | AppNavigationRequestMessage | GuidyElementsMessage | GuidyRoutesMessage | GuidyPointAckMessage | DocySendMessage | ChatSendMessage | EmailSendMessage | CalendarSendMessage | MsGraphStatusRequestMessage | MsGraphRequestMessage; /** Handler invoked when the host sends a navigation message */ type HostNavigationHandler = (message: HostNavigationMessage) => void; /** Handler invoked when the host sends a notification message */ type HostNotificationHandler = (notification: DocyrusNotification) => void; /** A role object as returned by GET /v1/users/me */ interface DocyrusRole { uid: string; slug: string; rules: DocyrusAclRule[]; } /** * An ACL rule — maps a data source to its allowed operations. * * Legacy shape, superseded by {@link DocyrusPermission}: every entity-less rule * (ai/settings/devtools) and every app/ai-tool rule collapses into the single * entry whose `dataSourceId` is null. */ interface DocyrusAclRule { dataSourceId: string | null; allowedOperations: string[]; } /** The entity an ACL rule applies to (`core_acl_operation.target_type`) */ type AclTargetType = 'data_source' | 'field' | 'app' | 'ai_tool' | 'ai' | 'settings' | 'devtools'; /** * A permission as returned by GET /v1/users/me, merged across the user's roles * and keyed by target type. Entity-scoped targets carry the single id that * scopes them (`data_source`/`field` → dataSourceId, `app` → appId, `ai_tool` * → aiToolId); `ai`, `settings` and `devtools` are tenant-wide and carry none. */ interface DocyrusPermission { targetType: AclTargetType; dataSourceId?: string | null; appId?: string | null; aiToolId?: string | null; allowedOperations: string[]; } /** * What a permission check applies to. Omit every id to check a tenant-wide * operation such as `ai-access` or `manage_users`. */ interface PermissionScope { dataSourceId?: string | null; appId?: string | null; aiToolId?: string | null; /** Narrow the check to one target type; inferred from the ids when omitted. */ targetType?: AclTargetType; } /** The user object as returned by GET /v1/users/me */ interface DocyrusUser { id: string; email: string; firstname?: string | null; lastname?: string | null; photo?: string | null; primaryRole: DocyrusRole | null; roles: DocyrusRole[]; aclRules: DocyrusAclRule[]; /** * Target-type-aware permissions. Absent on older API versions, where * `aclRules` is the only shape available. */ permissions?: DocyrusPermission[]; tenant?: { id: string; name: string; no: number; logo_url?: string | null; isDevelopmentAccount: boolean; } | null; [key: string]: unknown; } /** ACL operation identifier */ type AclOperation = 'view' | 'create' | 'edit' | 'delete' | 'create_bulk' | 'delete_bulk' | 'export' | 'export_bulk' | 'import' | 'print' | 'print_bulk'; /** Configuration for permission checking behavior */ interface PermissionConfig { /** * Data sources that are always permitted for certain operations, * keyed by data source UUID to an array of allowed operations. * Defaults to the standard Docyrus system data sources. */ alwaysPermittedDataSources?: Record; } export { IframeAuth as $, type AclOperation as A, type ChatSendAckMessage as B, type CalendarSendAckMessage as C, type DocyrusAuthConfig as D, type ChatSendMessage as E, type DocySendAckMessage as F, type GuidyRoute as G, type HostNavigationHandler as H, type DocySendMessage as I, type DocyrusNotification as J, type EmailSendAckMessage as K, type EmailSendMessage as L, type MsGraphAccount as M, type GuidyCommandHandler as N, type OpenAuthSessionFn as O, type PermissionConfig as P, type GuidyCommandMessage as Q, type RouteChangePayload as R, type GuidyElement as S, type GuidyElementsMessage as T, type GuidyPointAckMessage as U, type GuidyPointMessage as V, type GuidyRoutesMessage as W, type GuidyScanMessage as X, type HostNavigationMessage as Y, type HostNotificationMessage as Z, type HostSignInMessage as _, type AclTargetType as a, type MsGraphRequestMessage as a0, type MsGraphResponseMessage as a1, type MsGraphStatusRequestMessage as a2, type MsGraphStatusResponseMessage as a3, type TokenRefreshRequestMessage as a4, type AdaptiveCard as b, type AuthMode as c, type AuthSessionResult as d, type AuthStatus as e, type DocyrusAclRule as f, type DocyrusAuthContextValue as g, type DocyrusCalendarEventPayload as h, type DocyrusEmailPayload as i, type DocyrusPermission as j, type DocyrusRole as k, type DocyrusShareAdaptiveCardPayload as l, type DocyrusSharePayload as m, type DocyrusShareTextPayload as n, type DocyrusUser as o, MsGraphClient as p, type MsGraphRequest as q, type MsGraphRequestOptions as r, type MsGraphResponse as s, type MsGraphStatus as t, type PermissionScope as u, type HostNotificationHandler as v, type HostNavigationRequestOptions as w, type AppNavigationRequestMessage as x, type AppRouteChangeMessage as y, type CalendarSendMessage as z };