Using atlassian-connect-express-template, do I need to define an /installed route?

I am using out-of-the box atlassian-connect-express-template and have deployed it to Azure App Service. Other than adding a web.config (needed by Azure) and specifying the baseUrl in atlassian-connect.json, I have made no other changes.

When I attempt to ‘Upload add-on’ in my Jira Cloud instance, pointing to the correct baseUrl, I get an error stating that,

The add-on host did not respond when we tried to contact it at “https://.azurewebsites.net//installed” during installation (the attempt timed out). Please try again later or contact the add-on vendor.

Reading some doco … Security for Jira Cloud apps implies that I need a callback at /installed and that this should store the JWT token info. BUT, Bitbucket seems to imply that atlassian-connect-express should manage this automatically.

So, do I need to implement the /installed route myself? If so, what am I expected to implement, does anyone have any examples. If not, I’m guessing the issue may be with Azure … has anyone hosted an atlassian-connect-express app in Azure?

Thanks for any help with this

Answering my own question … I can confirm that there is a route configured by atlassian-connect-express … a POST to /installed

However this is not working when deployed to Azure App Service … it responds with a 401 and “You do not have permission to view this directory or page.”

I don’t understand this, because I have successfully made GET requests to routes that I have configured.

I suspect web.config … anyone any ideas?

<configuration>
     <system.webServer>
          <staticContent>
              <mimeMap fileExtension=".json" mimeType="application/json" />
          </staticContent>     
          <handlers>
               <!-- indicates that the app.js file is a node.js application to be handled by the iisnode module -->
               <add name="iisnode" path="app.js" verb="*" modules="iisnode"/>
          </handlers>
          <rewrite>
               <rules>
                    
                    <!-- Don't interfere with requests for node-inspector debugging -->
                    <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">                    
                        <match url="^app.js\/debug[\/]?" />
                    </rule>

                    <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
                    <rule name="StaticContent">
                         <action type="Rewrite" url="public{REQUEST_URI}"/>
                    </rule>

                    <!-- All other URLs are mapped to the Node.js application entry point -->
                    <rule name="DynamicContent">
                         <conditions>
                              <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
                         </conditions>
                         <action type="Rewrite" url="app.js"/>
                    </rule>

               </rules>
          </rewrite>
          <!-- You can control how Node is hosted within IIS using the following options -->
        <!--<iisnode      
          node_env="%node_env%"
          nodeProcessCommandLine="&quot;%programfiles%\nodejs\node.exe&quot;"
          nodeProcessCountPerApplication="1"
          maxConcurrentRequestsPerProcess="1024"
          maxNamedPipeConnectionRetry="3"
          namedPipeConnectionRetryDelay="2000"      
          maxNamedPipeConnectionPoolSize="512"
          maxNamedPipePooledConnectionAge="30000"
          asyncCompletionThreadCount="0"
          initialRequestBufferSize="4096"
          maxRequestBufferSize="65536"
          watchedFiles="*.js"
          uncFileChangesPollingInterval="5000"      
          gracefulShutdownTimeout="60000"
          loggingEnabled="true"
          logDirectoryNameSuffix="logs"
          debuggingEnabled="true"
          debuggerPortRange="5058-6058"
          debuggerPathSegment="debug"
          maxLogFileSizeInKB="128"
          appendToExistingLog="false"
          logFileFlushInterval="5000"
          devErrorsEnabled="true"
          flushResponse="false"      
          enableXFF="false"
          promoteServerVars=""
         />-->
        <iisnode watchedFiles="*.js;node_modules\*;routes\*.js;views\*.hbs"/>
     </system.webServer>
</configuration>