Skip to content
Snippets Groups Projects
cert-emails-test.js 4.65 KiB
Newer Older
Ben Adida's avatar
Ben Adida committed
#!/usr/bin/env node

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Ben Adida's avatar
Ben Adida committed

require('./lib/test_env.js');

const assert = require('assert'),
vows = require('vows'),
start_stop = require('./lib/start-stop.js'),
wsapi = require('./lib/wsapi.js'),
ca = require('../lib/keysigner/ca.js'),
jwk = require('jwcrypto/jwk'),
jwt = require('jwcrypto/jwt');
Ben Adida's avatar
Ben Adida committed

var suite = vows.describe('cert-emails');

Ben Adida's avatar
Ben Adida committed
// disable vows (often flakey?) async error behavior
suite.options.error = false;

start_stop.addStartupBatches(suite);

// INFO: some of these tests are repeat of sync-emails... to set
// things up properly for key certification

// create a new account via the api with (first address)
suite.addBatch({
Ben Adida's avatar
Ben Adida committed
    topic: wsapi.post('/wsapi/stage_user', {
      email: 'syncer@somehost.com',
Ben Adida's avatar
Ben Adida committed
    }),
      assert.strictEqual(r.code, 200);
    }
  }
});

// wait for the token
suite.addBatch({
  "a token": {
    topic: function() {
      start_stop.waitForToken(this.callback);
    },
    "is obtained": function (t) {
      assert.strictEqual(typeof t, 'string');
Ben Adida's avatar
Ben Adida committed
    }
  }
});

suite.addBatch({
  "verifying account ownership": {
    topic: function() {
      wsapi.post('/wsapi/complete_user_creation', { token: token }).call(this);
Ben Adida's avatar
Ben Adida committed
    },
Ben Adida's avatar
Ben Adida committed
      assert.equal(r.code, 200);
      assert.strictEqual(true, JSON.parse(r.body).success);
Ben Adida's avatar
Ben Adida committed
    }
  }
});

var cert_key_url = "/wsapi/cert_key";

// generate a keypair, we'll use this to sign assertions, as if
// this keypair is stored in the browser localStorage
var kp = jwk.KeyPair.generate("RS",64);
Ben Adida's avatar
Ben Adida committed

Ben Adida's avatar
Ben Adida committed
suite.addBatch({
  "check the public key": {
    topic: wsapi.get("/pk"),
      assert.strictEqual(r.code, 200);
    },
    "returns the right public key": function(err, r) {
      var pk = jwk.PublicKey.deserialize(r.body);
      assert.ok(pk);
    }
  },
Ben Adida's avatar
Ben Adida committed
  "cert key with no parameters": {
    topic: wsapi.post(cert_key_url, {}),
    "fails with HTTP 400" : function(err, r) {
Ben Adida's avatar
Ben Adida committed
      assert.strictEqual(r.code, 400);
    }
  },
  "cert key invoked with just an email": {
Ben Adida's avatar
Ben Adida committed
    topic: wsapi.post(cert_key_url, { email: 'syncer@somehost.com' }),
Ben Adida's avatar
Ben Adida committed
      assert.strictEqual(r.code, 400);
    }
  },
  "cert key invoked with proper argument": {
    topic: wsapi.post(cert_key_url, {
      email: 'syncer@somehost.com',
      pubkey: kp.publicKey.serialize(),
      ephemeral: false
    }),
    "returns a response with a proper content-type" : function(err, r) {
Ben Adida's avatar
Ben Adida committed
      assert.strictEqual(r.code, 200);
    },
    "returns a proper cert": function(err, r) {
      ca.verifyChain('127.0.0.1', [r.body], function(pk) {
Ben Adida's avatar
Ben Adida committed
        assert.isTrue(kp.publicKey.equals(pk));
      });
    },
    "generate an assertion": {
        var serializedCert = r.body.toString();
        var expiration = new Date(new Date().getTime() + (2 * 60 * 1000));
        var assertion = new jwt.JWT(null, expiration, "rp.com");
        var full_assertion = {
          certificates: [serializedCert],
          assertion: assertion.sign(kp.secretKey)
        };

        return full_assertion;
      },
      "full assertion looks good": function(full_assertion) {
        assert.equal(full_assertion.certificates[0].split(".").length, 3);
        assert.equal(full_assertion.assertion.split(".").length, 3);
      },
      "assertion verifies": {
        topic: function(full_assertion) {
Ben Adida's avatar
Ben Adida committed
          var cb = this.callback;
          // extract public key at the tail of the chain
          ca.verifyChain('127.0.0.1', full_assertion.certificates, function(pk) {
Ben Adida's avatar
Ben Adida committed
            if (!pk)
              cb(false);
Ben Adida's avatar
Ben Adida committed
            var assertion = new jwt.JWT();
            assertion.parse(full_assertion.assertion);
            cb(assertion.verify(pk));
          });
Ben Adida's avatar
Ben Adida committed
        "verifies": function(result, err) {
          assert.isTrue(result);
Ben Adida's avatar
Ben Adida committed
    }
  "cert key invoked proper arguments but incorrect email address": {
    topic: wsapi.post(cert_key_url, {
      email: 'syncer2@somehost.com',
      pubkey: kp.publicKey.serialize(),
      ephemeral: false
    }),
    "returns a response with a proper error content-type" : function(err, r) {
      assert.strictEqual(r.code, 400);
    }
Ben Adida's avatar
Ben Adida committed
  }
});

start_stop.addShutdownBatches(suite);

// run or export the suite.
if (process.argv[1] === __filename) suite.run();
else suite.export(module);