123 lines · 3.7 KB · TypeScript
RawDownload
import type { ConnectionId, ScopeId } from "@executor-js/sdk/core"; import { oauth2ClientSecretSlot } from "./store";import type { ConfiguredHeaderValue, OpenApiSourceBindingValue } from "./types"; export type BindingRowForCredentialStatus = {  readonly slot: string;  readonly scopeId: ScopeId;  readonly value: OpenApiSourceBindingValue;}; export type SourceForCredentialStatus = {  readonly config: {    readonly headers?: Record<string, ConfiguredHeaderValue>;    readonly oauth2?: {      readonly securitySchemeName: string;      readonly flow: "authorizationCode" | "clientCredentials";      readonly clientIdSlot: string;      readonly clientSecretSlot: string | null;      readonly connectionSlot: string;    };  };}; const scopeRank = (ranks: ReadonlyMap<string, number>, scopeId: ScopeId): number =>  ranks.get(scopeId as string) ?? Number.MAX_SAFE_INTEGER; export const effectiveBindingForScope = (  rows: readonly BindingRowForCredentialStatus[],  slot: string,  targetScope: ScopeId,  ranks: ReadonlyMap<string, number>,): BindingRowForCredentialStatus | null =>  rows    .filter(      (row) =>        row.slot === slot &&        scopeRank(ranks, row.scopeId) >= scopeRank(ranks, targetScope),    )    .sort(      (a, b) =>        scopeRank(ranks, a.scopeId) -        scopeRank(ranks, b.scopeId),    )[0] ?? null; const hasSecretBinding = (  rows: readonly BindingRowForCredentialStatus[],  slot: string,  targetScope: ScopeId,  ranks: ReadonlyMap<string, number>,) => effectiveBindingForScope(rows, slot, targetScope, ranks)?.value.kind === "secret"; const hasConnectionBinding = (  rows: readonly BindingRowForCredentialStatus[],  slot: string,  targetScope: ScopeId,  ranks: ReadonlyMap<string, number>,  liveConnectionIds?: ReadonlySet<string>,) => {  const binding = effectiveBindingForScope(rows, slot, targetScope, ranks);  if (binding?.value.kind !== "connection") return false;  return liveConnectionIds    ? liveConnectionIds.has(binding.value.connectionId as string)    : true;}; const effectiveClientSecretSlot = (oauth2: {  readonly securitySchemeName: string;  readonly clientSecretSlot: string | null;}): string => oauth2.clientSecretSlot ?? oauth2ClientSecretSlot(oauth2.securitySchemeName); export function missingCredentialLabels(  source: SourceForCredentialStatus,  bindings: readonly BindingRowForCredentialStatus[],  targetScope: ScopeId,  ranks: ReadonlyMap<string, number>,  options?: {    readonly liveConnectionIds?: ReadonlySet<string> | readonly ConnectionId[];  },): string[] {  const missing: string[] = [];  const rawLiveConnectionIds = options?.liveConnectionIds;  const liveConnectionIds = rawLiveConnectionIds    ? rawLiveConnectionIds instanceof Set      ? rawLiveConnectionIds      : new Set([...rawLiveConnectionIds].map((id) => id as string))    : undefined;   for (const [headerName, value] of Object.entries(source.config.headers ?? {})) {    if (typeof value === "string") continue;    if (!hasSecretBinding(bindings, value.slot, targetScope, ranks)) {      missing.push(headerName);    }  }   const oauth2 = source.config.oauth2;  if (!oauth2) return missing;   if (!hasSecretBinding(bindings, oauth2.clientIdSlot, targetScope, ranks)) {    missing.push("Client ID");  }   const clientSecretSlot = effectiveClientSecretSlot(oauth2);  if (!hasSecretBinding(bindings, clientSecretSlot, targetScope, ranks)) {    missing.push("Client Secret");  }   if (    !hasConnectionBinding(      bindings,      oauth2.connectionSlot,      targetScope,      ranks,      liveConnectionIds,    )  ) {    missing.push(      oauth2.flow === "clientCredentials" ? "OAuth client connection" : "OAuth sign-in",    );  }   return missing;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t