UNPKG

librecast-auth

Version:

Library to access Librecast authentication over multicast from the browser

148 lines (145 loc) 5.38 kB
const authComboKeyHex = "5c146391d0bf788c19ae63ff5cd64a2b23f2c9835edd8197a93bd1bab12e2a7d3a787c20db2c95e462340cea6e6584f7c5bf1a25b40682fcaa1f45fb40cce1f8"; QUnit.module('account signup', function() { const lctx = new LIBRECAST.Context(); QUnit.test('new user account - bad email address', function(assert) { console.log("== TEST: new user account - bad email address"); assert.timeout(2000); const done = assert.async(3); Promise.all([sodium.ready, lctx.onconnect]) .then(function () { assert.ok(true, "sodium ready"); const kp = sodium.crypto_box_keypair(); const localpart = sodium.to_hex(sodium.randombytes_buf(16)); const invalidEmail = "@live.librecast.net"; const password = sodium.to_hex(sodium.randombytes_buf(16)); const auth = new Auth(lctx, authComboKeyHex, kp, (opcode, flags, fields, pre) => { const view = new DataView(pre); const responseCode = view.getUint8(0).toString(); assert.ok(opcode === 0x1, "opcode=" + opcode); assert.ok(responseCode === "1", "signup rejected"); auth.close(); done(); }); auth.ready.then( () => { assert.ok(true, "auth ready"); auth.signup(invalidEmail, password); done(); }); done(); }); }); QUnit.test('use bad token', function(assert) { console.log("== TEST: set password - bad token"); assert.timeout(2000); const done = assert.async(1); Promise.all([sodium.ready, lctx.onconnect]) .then(function () { const kp = sodium.crypto_box_keypair(); const token = sodium.to_hex(sodium.randombytes_buf(16)); const password = sodium.to_hex(sodium.randombytes_buf(16)); const auth = new Auth(lctx, authComboKeyHex, kp, (opcode, flags, fields, pre) => { const view = new DataView(pre); const responseCode = view.getUint8(0).toString(); assert.ok(opcode === 0x4, "opcode=" + opcode); assert.ok(responseCode === "1", "token rejected"); auth.close(); done(); }); auth.ready.then(() => { assert.ok(true, "auth ready"); auth.setPassword(token, password); }); }); }); QUnit.test('bad login', function(assert) { console.log("== TEST: login - bad login"); assert.timeout(2000); const done = assert.async(1); Promise.all([sodium.ready, lctx.onconnect]) .then(function () { const kp = sodium.crypto_box_keypair(); const localpart = sodium.to_hex(sodium.randombytes_buf(16)); const email = localpart + "@live.librecast.net"; const password = sodium.to_hex(sodium.randombytes_buf(16)); const auth = new Auth(lctx, authComboKeyHex, kp, (opcode, flags, fields, pre) => { const view = new DataView(pre); const responseCode = view.getUint8(0).toString(); assert.ok(opcode === 0x8, "opcode=" + opcode); assert.ok(responseCode === "1", "login failed"); auth.close(); done(); }) auth.ready.then(() => { assert.ok(true, "auth ready"); auth.login(email, password); }); }); }); QUnit.test('new user account', function(assert) { console.log("== TEST: new user account"); assert.timeout(3000); const done = assert.async(1); let signup = false; let passet = false; let login = false; Promise.all([sodium.ready, lctx.onconnect]) .then(function () { const kp = sodium.crypto_box_keypair(); const localpart = sodium.to_hex(sodium.randombytes_buf(32)); const email = localpart + "@live.librecast.net"; const password = sodium.to_hex(sodium.randombytes_buf(16)); const seed = kp.publicKey.slice(0, sodium.randombytes_SEEDBYTES); const token = sodium.to_hex(sodium.randombytes_buf_deterministic(sodium.crypto_box_PUBLICKEYBYTES, seed)); const hextoken = sodium.to_hex(token); const auth = new Auth(lctx, authComboKeyHex, kp, (opcode, flags, fields, pre) => { const view = new DataView(pre) const responseCode = view.getUint8(0).toString(); console.log("opcode: " + opcode); console.log("responseCode: " + responseCode); switch (opcode) { case 0x1: if (!signup) { signup = true; assert.ok(responseCode === "0", "signup confirmed"); if (responseCode === "0") { auth.setPassword(token, password); } } else { console.warn("duplicate signup response received"); } break; case 0x4: if (!passet) { passet = true; assert.ok(responseCode === "0", "token used, password set"); if (responseCode === "0") { auth.login(email, password) } } else { console.warn("duplicate password set response received"); } break; case 0x8: if (!login) { login = true; assert.ok(responseCode === "0", "login successful"); const capClear = auth.checkSignature(fields[1]); assert.ok(capClear, "signature checked"); const capFields = util.wireUnpack7Bit(capClear.buffer, 8); assert.ok(capFields.length === 3, "token has 3 fields"); /* TODO: check expires (pre 8 bytes of token) */ assert.ok(util.keysEqual(capFields[0], kp.publicKey), "token key matches"); assert.strictEqual(sodium.to_string(capFields[1]), "service", "service matches"); auth.close(); done(); } else { console.warn("duplicate login response received"); } break; default: throw "unknown opcode " + opcode + " received"; } }, 1); auth.ready.then(() => { auth.signup(email, password); }); }); }); });