import { type Settings } from "@opengeni/config"; import { OAuthStartResponse, type SocialConnection, type SocialOAuthProviderId, type SocialOAuthStartRequest } from "@opengeni/contracts"; import type { Observability } from "@opengeni/observability"; import { type Database } from "@opengeni/db"; export declare const SOCIAL_USER_AGENT = "opengeni:social-connector:v0.1.0 (self-hosted)"; export declare const SOCIAL_TIMEOUT_MS = 10000; /** Token-endpoint failure that carries enough to tell invalid_grant from a blip. */ export declare class SocialTokenRequestError extends Error { readonly status: number | null; readonly oauthError: string | null; constructor(message: string, status: number | null, oauthError: string | null); /** True only for definitive authorization-server rejections of the grant. */ get definitive(): boolean; } type SocialProviderDefinition = { id: SocialOAuthProviderId; authorizationEndpoint: string; tokenEndpoint: string; defaultScopes: string[]; pkce: boolean; extraAuthorizeParams: Record; }; export declare const SOCIAL_OAUTH_PROVIDERS: Record; export type SocialCredentialBundle = { provider: SocialOAuthProviderId; accessToken: string; refreshToken?: string; tokenType: string; expiresAt?: string; scope?: string; }; /** * Provider-transport seam (Slack-connector pattern): production always goes * through pinnedFetch; tests inject an in-process provider to exercise the * full callback/refresh/tool loop functionally. */ export type SocialProviderFetch = (url: string, init: RequestInit, label: string) => Promise; type SocialOAuthDeps = { db: Database; settings: Settings; observability?: Observability | undefined; providerFetch?: SocialProviderFetch | undefined; }; export type SocialOAuthStartContext = { connectAttemptId?: string; accountId: string; workspaceId: string; subjectId: string; /** * False for every principal that cannot own a personal Connection. Resolved * by the route from the live authenticated principal, never inferred here. */ personalOwnershipAllowed: boolean; requestUrl: string; payload: SocialOAuthStartRequest; }; export declare function socialOAuthClientFor(settings: Settings, provider: SocialOAuthProviderId): { clientId: string; clientSecret?: string | undefined; }; export declare function socialOAuthRedirectUri(settings: Settings, requestUrl: string): string; export declare function startSocialOAuth(deps: SocialOAuthDeps, context: SocialOAuthStartContext): Promise; export declare function completeSocialOAuthCallback(deps: SocialOAuthDeps, input: { code?: string | undefined; state?: string | undefined; error?: string | undefined; requestUrl: string; }): Promise<{ redirectTo: string; exactReturn?: boolean; }>; /** * Resolves a usable access token for a social connection, refreshing (and * persisting the rotated bundle) when the stored token is near expiry. Marks * the connection needs_reauth and throws when refresh is impossible so agents * surface an actionable error instead of opaque 401s. */ export declare function freshSocialAccessToken(deps: SocialOAuthDeps, ref: { workspaceId: string; connectionId: string; subjectId?: string | null; }): Promise<{ connection: SocialConnection; bundle: SocialCredentialBundle; }>; export declare function markNeedsReauth(deps: SocialOAuthDeps, ref: { workspaceId: string; connectionId: string; subjectId?: string | null; }): Promise; export declare function parseSocialCredentialBundle(raw: string): SocialCredentialBundle; export declare function socialTokenNeedsRefresh(bundle: SocialCredentialBundle, now: Date): boolean; export {};