/** * Credential form HTML renderer. * * Renders a dark-themed HTML form from a RelayConfigSchema. * Used as the OAuth authorization page presented to the user during relay config. * * This is a TypeScript port of core-py's `credential_form.py`. CSS and embedded JS * are kept verbatim so the rendered form has visual + behavioral parity between * Python and TS servers. */ export interface ConfigField { key: string; label: string; type: string; placeholder?: string; helpText?: string; helpUrl?: string; required?: boolean; /** Regex string for client-side validation; rendered as the input's `pattern` attribute. */ validation?: string; } /** * Return true iff every required field in `schema` has a non-empty value in * `config`. For schemas whose fields are all optional, requires the explicit * `_setup_complete: "true"` flag — see core-py `is_schema_complete` docstring. * * Strict equality on the flag: only the literal string `"true"` counts. This * guards against legacy / partial bootstrap entries (e.g. peer-shared cloud * keys) tricking the auto-open gate into thinking the user has configured. */ export declare function isSchemaComplete(config: Record | null | undefined, schema: RelayConfigSchema): boolean; export interface CapabilityInfo { label: string; priority?: string; description?: string; } /** * A credential-form tab (schema-level `tabs` capability). Each tab is a * mutually-exclusive credential mode; only the active tab's fields submit. */ export interface TabGroup { id: string; label: string; fields: ConfigField[]; } /** * A repeatable field group (schema-level `cardGroup` capability). Renders * Add/Remove cards, each cloning `fields`; submitted as a JSON array under * `key` (e.g. `{ accounts: [{...}, {...}] }`). */ export interface CardGroup { key: string; fields: ConfigField[]; itemLabel?: string; heading?: string; addButtonLabel?: string; minItems?: number; titleField?: string; } export interface RelayConfigSchema { server: string; displayName?: string; description?: string; fields?: ConfigField[]; capabilityInfo?: CapabilityInfo[]; /** Mutually-exclusive credential modes; see the tabbed render path. */ tabs?: TabGroup[]; /** One repeatable field group; see the card-group render path. */ cardGroup?: CardGroup; } export interface RenderOptions { submitUrl: string; pageTitle?: string; /** * Optional ``{KEY: VALUE}`` map populated by the OAuth AS from * ``?prefill_=`` query params on GET /authorize. Each matching * field renders with an HTML-escaped ``value="..."`` attr so users only * type what skret cannot supply (OTP / 2FA / one-time codes). Non-matching * keys are ignored. */ prefill?: Record; /** * For a `tabs` schema, the id of the tab to render active on load (defaults * to the first tab). Ignored for non-tabbed schemas. */ initialTab?: string; /** * Opt-in workspace-username field (multi-user stable-sub). Honoured by the * flat, `tabs`, and `cardGroup` render paths. */ includeUsernameField?: boolean; } /** * Wrap `bodyHtml` in the shared dark-theme HTML shell. * * The shell provides ``, `` (charset, viewport, a * Content-Security-Policy meta, escaped ``, embedded `FORM_SHELL_CSS`) * and a `<body>` whose only child is `bodyHtml`. `bodyHtml` is inserted * verbatim, so callers MUST pre-escape any untrusted values they interpolate. * * The CSP (`default-src 'none'; style-src 'unsafe-inline'; script-src * 'unsafe-inline'; connect-src 'self'`) permits the page's own inline * `<style>`/`<script>` and same-origin `fetch` submits while blocking any * external resource load. * * `title` is HTML-escaped before being placed in `<title>`. * * Used by `renderCredentialForm` (relay credential form) and by * `loginGetHandler` in `relay-login.ts` (the `/login` password gate) so both * pages share identical typography, palette, card layout, and input styling. * Parity with Python `render_form_shell` in * `packages/core-py/src/mcp_core/auth/credential_form.py`. */ export declare function renderFormShell(title: string, bodyHtml: string): string; /** * Render a dark-themed HTML credential form from a RelayConfigSchema. * * @param schema RelayConfigSchema with server metadata and field definitions. * @param options.submitUrl URL the form POSTs to as JSON via fetch(). * @param options.pageTitle Optional browser tab title. Defaults to displayName. * @param options.prefill Optional ``{KEY: VALUE}`` map for input ``value=`` attrs. * @returns Complete HTML document string, XSS-safe with all dynamic content escaped. */ export declare function renderCredentialForm(schema: RelayConfigSchema, options: RenderOptions): string; /** * Relay config field schema (D7). * * Each field supports: * name (string, required): config.enc key * label (string, required): UI label * required (boolean, required): server gate * secret (boolean, optional, default false): true = never re-render value to HTML * oauthField (boolean, optional, default false): true = managed by OAuth flow, * render as Re-authorize button instead of input * type (string, optional, default "text"): UI input type * description (string, optional): help text * default (unknown, optional): default value if user submits empty * pattern (string, optional): client-side regex validation * * Parity with core-py `RelayConfigField` (snake_case `oauth_field` -> camelCase * `oauthField` per TS convention). */ export interface RelayConfigField { name: string; label: string; required: boolean; secret?: boolean; oauthField?: boolean; type?: 'text' | 'password' | 'url' | 'email'; description?: string; default?: unknown; pattern?: string; } /** Return true if field stores a credential that must not be re-rendered to HTML. */ export declare function isSecretField(field: RelayConfigField): boolean; /** * Return true if field represents an OAuth-managed credential. * * OAuth fields render as "Re-authorize" buttons, not raw input boxes. * Examples: refresh_token, access_token, id_token. */ export declare function isOAuthField(field: RelayConfigField): boolean; //# sourceMappingURL=credential-form.d.ts.map