ACE lifecycle events other than "installed" are failing with 401 or 404

I’m running atlassian-connect-express 7.4.7 with the following:

/atlassian-connect.json

{
  ...
  "lifecycle": {
    "installed": "/installed",
    "uninstalled": "/uninstalled",
    "enabled": "/enabled",
    "disabled": "/disabled"
  },
  "webhooks": [
    {
      "event": "connect_addon_enabled",
      "url": "/webhooks/connect_addon_enabled"
    },
    {
      "event": "connect_addon_disabled",
      "url": "/webhooks/connect_addon_disabled"
    },
    ...
  ],
  ...
}

/routes/index.js

  const onLifecyleEvent = (req, res, next) => {
    ...
    next();
  };
  
  // Lifecycle events
  app.post("/installed", addon.authenticateInstall(), onLifecyleEvent);
  app.post("/uninstalled", addon.authenticateInstall(), onLifecyleEvent);
  app.post("/enabled", addon.authenticateInstall(), onLifecyleEvent);
  app.post("/disabled", addon.authenticateInstall(), onLifecyleEvent);
  
  
  // Webhooks e.g. "connect_addon_enabled" or "connect_addon_disabled"
  app.post("/rest/webhooks/:event_name", addon.authenticate(), (req, res) => {
    res.sendStatus(200);
  }

If I run the app in dev, then CTRL+C to stop it, I see the following (in this order):

POST /installed                           204 No Content  
POST /webhooks/connect_addon_enabled      200 OK                                                                                                                                                    
POST /enabled                             401 Unauthorized                                                                                                                                          
POST /uninstalled                         404 Not Found    
POST /webhooks/connect_addon_disabled     200 OK                                                                                                                                             
POST /disabled                            401 Unauthorized  

The install lifecycle event & webhooks behave well, but the enabled, uninstalled & disabled lifecycle events are not behaving as expected.

I’ve updated the node_modules/atlassian-jwt/dist/lib/jwt.js so that the error it throws adds the expected algorithm for these errors:

{} Authentication verification error (401):  Invalid JWT: Algorithm from the header "HS256" does not match the expected algorithm "RS256"

Is addon.authenticateInstall() incorrect for lifecycle events other than installed or am I missing something else?

Hi, only install and uninstall lifecycle hooks are protected with asymmetric JWT.
Please change enabled and disabled hook to use sharedSecret and test again. Also, uninstalled endpoint doesn’t seem to be defined, therefore the app is returning 404.

  app.post("/enabled", addon.authenticate(), onLifecyleEvent);
  app.post("/disabled", addon.authenticate(), onLifecyleEvent);

Thank you for this.

OK, on my dev system, I’ve updated to the following:

  // only install and uninstall lifecycle hooks are protected with asymmetric JWT, so need addon.authenticateInstall()
  app.post("/installed", addon.authenticateInstall(), onLifecyleEvent);
  app.post("/uninstalled", addon.authenticateInstall(), onLifecyleEvent);

  // normal authentication check
  app.post("/enabled", addon.authenticate(), onLifecyleEvent);
  app.post("/disabled", addon.authenticate(), onLifecyleEvent);

…with the same webhooks.

I now run npm run watch-server and get the following requests in this order:

GET  /atlassian-connect.json               200 OK    
POST /installed                            204 No Content                                                                                                                                                                                                                      
POST /enabled                              404 Not Found                                                                                                                                                                                                                        
POST /rest/webhooks/connect_addon_enabled  200 OK                                                                                                                                                                                                                              

On CTRL+C, the system shuts down and sends the following requests:

POST /rest/webhooks/connect_addon_disabled 200 OK                                                                                                                                                                                                                              
POST /disabled                             404 Not Found                                                                                                                                                                                                                       
POST /uninstalled                          404 Not Found                                                                                                                                                                                                                       

Note that for the routes that are 404ing, the onLifecyleEvent menthod is running, so it just looks like the http status is wrong somehow.

Hi, it seems like enabled, disabled and uninstalled lifecycle hooks routes are not defined.
ACE only provides installed hook by default and all other lifecycle endpoints should be implemented if it is required for you app.

No, they are all defined and working…

…but they are oddly throwing 404s. Most strange.