UNPKG

@microsoft/teams.apps

Version:

<p> <a href="https://www.npmjs.com/package/@microsoft/teams.apps" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.apps/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.apps?activeTab=code

76 lines (75 loc) • 3.58 kB
import { Client as HttpClient, ILogger } from '@microsoft/teams.common'; import { NegotiateResult } from './types'; /** * Dependencies for {@link negotiate}. Kept explicit so the call is unit-testable * without a live Teams backend service endpoint. */ export type NegotiateDeps = { /** Fully-resolved negotiate URL (`{base}/v3/websockets/connect`). */ readonly negotiateUrl: string; /** The app's shared HTTP client. */ readonly client: HttpClient; /** Acquire the Bot Framework access token, reusing the app's credentials. */ readonly getBotToken: () => Promise<string>; /** * Read the open, unexpired predecessor's exact ID after token acquisition. * Omit or return `undefined`/`""` to omit the planned-refresh replacement header. */ readonly getConnectionIdToReplace?: () => string | undefined; /** * Abort the negotiate request after this many milliseconds so a hung endpoint * can't leave the caller pending forever. Defaults to * {@link DEFAULT_NEGOTIATE_TIMEOUT_MS}. */ readonly timeoutMs?: number; readonly log?: ILogger; }; /** Default negotiate request timeout — bounds a hung or misconfigured endpoint. */ export declare const DEFAULT_NEGOTIATE_TIMEOUT_MS = 15000; /** * Reject a negotiate URL that isn't HTTPS. The negotiate request carries a Bot * Framework JWT in the `authorization` header; sending it over plaintext `http` * would leak that token. A narrow exception is made for loopback hosts * (`localhost`/`127.0.0.1`/`::1`) so local test endpoints still work. */ export declare function assertSecureNegotiateUrl(negotiateUrl: string): void; /** * Error thrown by {@link negotiate} when the service returns a non-2xx status. * Carries the HTTP status and the parsed `Retry-After` (in milliseconds) when * the service asked the caller to back off — typically on `429` or `503` — so * the reconnect supervisor can honor it instead of using its own back-off. * Authentication and authorization failures (`401`/`403`) are not retried; * see {@link NegotiateError.isAuthError}. */ export declare class NegotiateError extends Error { /** Service-requested delay before retrying, when supplied. */ readonly retryAfterMs?: number | undefined; /** * HTTP status returned by the Socket Mode negotiate endpoint. `undefined` * when the error was constructed without a status. */ readonly statusCode?: number | undefined; constructor(message: string, /** Service-requested delay before retrying, when supplied. */ retryAfterMs?: number | undefined, /** * HTTP status returned by the Socket Mode negotiate endpoint. `undefined` * when the error was constructed without a status. */ statusCode?: number | undefined); /** * `true` when negotiate was rejected with HTTP `401` or `403`. Retrying * cannot fix these until the bot's credentials or Socket Mode access are * corrected, so the SDK stops retrying on startup and reconnect. */ get isAuthError(): boolean; } /** * Perform the Teams backend service Socket Mode handshake: `POST {negotiateUrl}` authenticated * with a Bot Framework JWT minted from the bot's own credentials. Teams backend service returns * the Azure SignalR `url` + `accessToken` to open the socket against. * * @throws {NegotiateError} if Teams backend service returns a non-2xx response. * @throws if the bot token is missing (the app has no credentials configured). */ export declare function negotiate(deps: NegotiateDeps): Promise<NegotiateResult>;