linuxunixfirefox-addon-sdkunix-timestampjpm

Generating signed XPI via jpm failed


There was a problem signing an Add-On via jpm: The command

jpm -v sign --api-key 'user:xxxxxxxx:xxx' --api-secret xxxxxxxxxxxxxxxxxxxxxxxxx

failed with the error message

Error: Received bad response from the server while requesting https://addons.mozilla.org/api/v3/addons/%40addonname/versions/0.x.y/

Signing via the web interface worked.

How can this be fixed?


The full verbose output is

JPM [info] binary set to /usr/bin/firefox  
JPM [info] verbose set  
JPM [info] Checking compatability bootstrap.js and install.rdf for xpi  
Validating the manifest  
JPM [info] Creating fallbacks if they are necessary..  
Creating XPI  
JPM [info] Creating XPI...  
JPM [info] .jpmignore found  
JPM [info] Adding: /path/to/file  
[...]  
JPM [info] Adding: /path/to/another_file  
JPM [info] XPI created at /tmp/tmp-unsigned-xpi-25600yuqzFN3Alxa0/@addonname-0.x.y.xpi (121ms)  
JPM [info] Removing fallbacks if they were necessary..  
JPM [info] Creating updateRDF...  
Created XPI at /tmp/tmp-unsigned-xpi-25600yuqzFN3Alxa0/@addonname-0.x.y.xpi  
JPM [info] Created XPI for signing: /tmp/tmp-unsigned-xpi-25600yuqzFN3Alxa0/@addonname-0.x.y.xpi  
JPM [debug] [API] -{ url: 'https://addons.mozilla.org/api/v3/addons/%40addonname/versions/0.x.y/',  
  formData:   
   { upload:   
      { _readableState: [Object],  
        readable: true,  
        domain: null,  
        _events: [Object],  
        _eventsCount: 1,  
        _maxListeners: undefined,  
        path: '/tmp/tmp-unsigned-xpi-25600yuqzFN3Alxa0/@addonname-0.x.y.xpi',  
        fd: null,  
        flags: 'r',  
        mode: 438,  
        start: undefined,  
        end: undefined,  
        autoClose: true,  
        pos: undefined } },  
  headers: { Authorization: '<REDACTED>', Accept: 'application/json' } }  
JPM [debug] [API] <- { headers:   
   { allow: 'GET, PUT, HEAD, OPTIONS',  
     'content-type': 'application/json',  
     date: 'Thu, 17 Dec 2015 10:17:23 GMT',  
     server: 'nginx',  
     'set-cookie': '<REDACTED>',  
     'strict-transport-security': 'max-age=31536000',  
     vary: 'Accept, X-Mobile, User-Agent',  
     'www-authenticate': 'JWT realm="api"',  
     'x-frame-options': 'DENY',  
     'content-length': '51',  
     connection: 'Close' },  
  response: { detail: 'Incorrect authentication credentials.' } }  
JPM [error] FAIL  
Error: Received bad response from the server while requesting https://addons.mozilla.org/api/v3/addons/%40addonname/versions/0.x.y/  

status: 401  
response: {"detail":"Incorrect authentication credentials."}  
headers: {"allow":"GET, PUT, HEAD, OPTIONS","content-type":"application/json","date":"Thu, 17 Dec 2015 10:17:23 GMT","server":"nginx","set-cookie":["multidb_pin_writes=y; expires=Thu, 17-Dec-2015 10:17:38 GMT; Max-Age=15; Path=/"],"strict-transport-security":"max-age=31536000","vary":"Accept, X-Mobile, User-Agent","www-authenticate":"JWT realm=\"api\"","x-frame-options":"DENY","content-length":"51","connection":"Close"}  

    at /usr/local/lib/node_modules/jpm/lib/amo-client.js:85:13  
    at tryCatchReject (/usr/local/lib/node_modules/jpm/node_modules/when/lib/makePromise.js:845:30)  
    at runContinuation1 (/usr/local/lib/node_modules/jpm/node_modules/when/lib/makePromise.js:804:4)  
    at Fulfilled.when (/usr/local/lib/node_modules/jpm/node_modules/when/lib/makePromise.js:592:4)  
    at Pending.run (/usr/local/lib/node_modules/jpm/node_modules/when/lib/makePromise.js:483:13)  
    at Scheduler._drain (/usr/local/lib/node_modules/jpm/node_modules/when/lib/Scheduler.js:62:19)  
    at Scheduler.drain (/usr/local/lib/node_modules/jpm/node_modules/when/lib/Scheduler.js:27:9)  
    at doNTCallback0 (node.js:417:9)  
    at process._tickCallback (node.js:346:13)

Solution

  • These posts (1), (2) show that this error can occur if your local clock is off by more than 60 seconds with the Mozilla server.

    This is also documented in the Olympia 3.0 Authentication API (see exp parameter):

    iat

    This is a standard JWT claim indicating the issued at time. It should be a Unix epoch timestamp and must be in UTC time.

    exp

    This is a standard JWT claim indicating the expiration time. It should be a Unix epoch timestamp in UTC time and must be no longer than 60 seconds past the issued at time.

    Note:

    If you’re having trouble authenticating, make sure your system clock is correct and consider synchronizing it with something like NTP (Network Time Protocol).