Skip to content

OAuth Flow for WebEx in i-Coach AI

Return URI

Use ngrok to provide a "public" url to local host.

powershell
ngrok config add-authtoken $YOUR_AUTHTOKEN
ngrok http --url=knelt-constable-quicken.ngrok-free.dev https://localhost:5573

https://knelt-constable-quicken.ngrok-free.dev will forward to https://localhost:5573.

The code uses the state query parameter to re-redirect to the original URI, which allows for the OAuth Token API to be called...

A Picture

mermaid
sequenceDiagram
  actor user
  participant client as Client
  participant ui as AI.UI Library
  participant auth as /v1/authorize
  participant webex as WebEx Login
  participant api as iCoach APIs
  participant token as /v1/access_token
  participant transcript as WebEx Transcripts

  user->>ui: Requests WebEx<br />meeting transcript(s)
  ui->>api: Checks for existing WebEx ID (Bearer) Token<br />GET /OAuth/Cached/WebEx
  api->>api: Checks SQL for<br />user's valid token
  api->>ui: Response contains existing ID Token or empty<br />includes environment data for OAuth flow
  alt NO existing ID Token
    ui->>auth: Request for Authorization Code (auto click)<br />Set state to the original URI
    user-->>webex: Authenticates with WebEx credentials<br>and accepts requested scopes
    webex->>client: Successful response to RedirectUri contains Auth Code and state<br />https://{proxy}/oauth/webex?code=auth_code&state=originalURI*
    client->>client: Redirect to original<br />(non-proxy) URI
    client->>api: GET /Oauth/Webex?code=auth_code&state=originalURI
    api->>token: Request for ID token
    token->>token: WebEx creates ID token
    token->>api: Response contains ID Token
    api->>api: OAuth data and ID token stored to SQL
    api->>client: Response contains new ID Token<br />includes environment data for OAuth flow
    client->>client: Store ID token in session state
    ui->>ui: Get ID Token from session state
  else Existing WebEx ID Token
    ui->>ui: Use ID Token from SQL response
  end
  ui->>api: UI requests Transcripts passing ID Token<br />GET /Transcripts?apiKey=IDToken
  api->>transcript: APIs request from WebEx with provided Token
  transcript-->>client: Response contains data from WebEx
  client->>user: Happy user

* This is the redirect URI defined in the OAuth (WebEx) provider. If it is not externally facing, it will require an externally facing proxy to call the internal URI. Internal (authenticated) APIs cannot be called from the proxy URI. Therefore, the original URI (before request) is added as state and can be re-used by the client application.

Simples.

Folders

The following files are changed to add transcripts to the chat, and to authenticate by OAuth.

ONLY appropriate files / folders are shown.

mermaid
---
config:
    treeView:
        rowIndent: 20
        lineThickness: 1
    themeVariables:
        treeView:
            labelFontSize: '16px'
            labelColor: '#999'
            lineColor: '#999'
---
treeView-beta
  "Imparta.AI.UI"
    "lib"
      "api"
        "transcript.api.ts"
      "components"
        "message.cards"
          "card.factory.tsx"
          "transcript.select.card.tsx"
      "types"
        "client.config.ts"
  "impartaaibot.client"
    "src"
      "api"
        "api.constants.ts"
      "oauth"
        "webex"
          "constants.ts"
          "OAuthLink.tsx"
          "OAuthReturnPage.tsx"
      "pages"
        "admin"
          "agents"
            "editor"
              "toolbox"
                "toolbox.general.tsx"
          "clients"
            "EditClientPage.tsx"
            "update.ts"
            "validation.ts"
          "modules"
            "EditModulePage.tsx"
            "types.ts"
            "validation.ts"
      "types"
        "WebExTranscriptsDto.ts"
      "main.tsx"
    ".env"
    ".env.development"
    ".env.production"
  "ImpartaAIBot.Database"
    "Scripts"
      "0041-WebEx Transcripts"
        "001 translations.sql"
        "002. Populate AgentToolType Table 1.sql"
        "003. More providers.sql"
        "004. Create OAuth2 Table.sql"
  "ImpartaAIBot.Server"
    "Controllers"
      "OAuthController.cs"
      "TranscriptsController.cs"
      "TranscriptsController.Gets.cs"
    "Models"
      "ClientConfiguration"
    "appsettings.Development.json"
    "appsettings.json"
    "Program.cs"
  "ImpartaAIBot.Shared"
    "DTOs"
      "TranscriptDto.cs"
      "TranscriptItemDto.cs"
      "TranscriptMeetingsDto.cs"
    "Entities"
      "iCoachAIContext.cs"
      "OAuth2.cs"
    "Extensions"
      "ServiceCollectionExtensions.cs"
    "Retries"
      "RetryPolicies.cs"
    "Services"
      "OAuth"
        "Models"
          "AccessTokenResponse.cs"
          "OAuthEntity.cs"
          "OAuthRedirectData.cs"
        "IOAuthService.cs"
        "OAuthService.cs"
        "OAuthSettings.cs"
      "Transcripts"
        "Models"
          "WebEx"
            "ErrorApiResponse.cs"
            "MeetingsApiResponse.cs"
            "TranscriptApiResponse.cs"
          "MeetingItemEntity.cs"
        "BaseTranscriptsService.cs"
        "ITranscriptsSercice.cs"
        "TranscriptsFactory.cs"
        "TranscriptsService.WebEx.cs"
        "TranscriptsSettings.cs"
    "efcpt-config.json"

TODO

  • When getting a single transcript, information is missing for (eg) name
    • Probably need to pass in the meeting object, not just the ID to return this data
  • Text translations are missing for the redirect page
  • View transcript is empty
    • Assess is correctly reading it...
  • The fetch for Transcript(s) seems to happen before the apiKey has been obtained... ??