'Custom app in Microsoft Teams can't connect to it's own API from desktop app

I am trying to embed our app into Teams. We have it working from the web version of MS Teams. However when we try it from the MS Teams desktop app, our app's tab is unable to communicate with our API saying net::ERR_BLOCKED_BY_RESPONSE for all XHR requests the app tries to make to the API. The OPTIONS request seems to get some response headers back but is still listed as failed (see header below)

What is blocking the requests in the Desktop app? We have tried various security header changes and disabling our apps service worker among other things but to no avail. The application loads fine (we have the iframe enabling headers set in the CSP - see below). It's just the communication with the API that is blocked.

Application details that we are embedding in the MS Teams APP as a custom app

  • Progressive web app
  • Angular v13 with
  • Angular routing strategy (useHash = false)
  • API is REST based

NB: The app tab works in the mobile app version of teams on iOS as well as on the web version

Devtools in Teams desktop app


Response headers that are returned by the API we are trying to talk to on the OPTIONS request

access-control-allow-headers: Content-Type, Authorization, V, D
access-control-allow-methods: OPTIONS, GET, POST, DELETE, PUT
access-control-allow-origin: https://**redacted**
access-control-max-age: 86400
cache-control: no-cache
content-length: 0
date: Wed, 12 Jan 2022 00:14:44 GMT
permissions-policy: geolocation=()
referrer-policy: no-referrer
server: CloudFront
status: 200
strict-transport-security: max-age=31536000; includeSubDomains
vary: Origin
via: 1.1 **redacted**.cloudfront.net (CloudFront)
x-amz-cf-id: **redacted**
x-amz-cf-pop: SYD62-P1
x-cache: Miss from cloudfront
x-content-type-options: nosniff
x-xss-protection: 1; mode=block

Headers and CSP on the application (SPA)

age: 6
cache-control: no-cache
content-encoding: br
content-security-policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://*.**redacted**.com https://**redacted**.app https://*.**redacted**.app; connect-src https://*.**redacted**.com https://**redacted**.app https://*.**redacted**.app; object-src 'none'; frame-ancestors teams.microsoft.com *.office.com outlook.office.com outlook.office365.com
content-type: text/html
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
date: Wed, 12 Jan 2022 00:22:58 GMT
etag: **redacted**
expect-ct: max-age=0, report-uri="https://**redacted**.report-uri.com/r/d/ct/reportOnly"
last-modified: Tue, 11 Jan 2022 23:27:02 GMT
permissions-policy: geolocation=()
referrer-policy: no-referrer-when-downgrade
server: CloudFront
status: 304
strict-transport-security: max-age=31536000; includeSubDomains
vary: Accept-Encoding
via: 1.1 **redacted**.cloudfront.net (CloudFront)
x-amz-cf-id: **redacted**
x-amz-cf-pop: SYD62-P1
x-cache: Hit from cloudfront
x-content-type-options: nosniff
x-xss-protection: 1; mode=block

The manifest, currently setup with a configure page that adds a tab after choosing our customer account name which generates the url for the tab.

{
    "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.11/MicrosoftTeams.schema.json",
    "manifestVersion": "1.11",
    "version": "4.1.8",
    "id": "***",
    "packageName": "app.***",
    "developer": {
        "name": "*** Pty Limited",
        "websiteUrl": "https://www.***.com",
        "privacyUrl": "https://www.***.com/privacy",
        "termsOfUseUrl": "https://***.com/resources/20201019+***+Terms+and+Conditions.pdf"
    },
    "icons": {
        "color": "color.png",
        "outline": "outline.png"
    },
    "name": {
        "short": "***",
        "full": "*** For Microsoft Teams"
    },
    "description": {
        "short": "***",
        "full": "***"
    },
    "accentColor": "#F9F9FA",
    "configurableTabs": [
        {
            "configurationUrl": "https://dev.***.app/ms-teams/teams-configure.html",
            "canUpdateConfiguration": true,
            "scopes": [
                "team"
            ],
            "context": [
                "channelTab"
            ],
            "supportedSharePointHosts": [
                "sharePointFullPage"
            ]
        }
    ],
    "permissions": [
        "identity",
        "messageTeamMembers"
    ],
    "validDomains": [
        "dev.***.app",
        "*.dev.***.app",
        "*.teams.***.app",
        "api.test.***.com",
        "api.***.com",
        "*.test.***.app",
        "*.***.app"
    ]
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source