test_group_close.html (4849B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test for Messaging Layer Security</title> 5 <!-- SimpleTest Helpers --> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 <!-- Local Helpers --> 9 <script src="head_mls.js"></script> 10 </head> 11 <body> 12 <pre id="test"> 13 <script class="testbody" type="text/javascript"> 14 15 async function test_group_close() { 16 17 const mls = new MLS(); 18 19 // Generate Identity KeyPairs for Alice and Bob 20 let alice = await mls.generateIdentity(); 21 let bob = await mls.generateIdentity(); 22 23 // Generate Credentials for Alice and Bob 24 let credential_alice = await mls.generateCredential("alice"); 25 let credential_bob = await mls.generateCredential("bob"); 26 27 // Generate a KeyPackage for Bob 28 let kp_bob = await mls.generateKeyPackage(bob, credential_bob); 29 30 // Creation of a Group by Alice 31 let group_alice = await mls.groupCreate(alice, credential_alice); 32 33 // Alice adds Bob to a group 34 let commit_output = await group_alice.add(kp_bob); 35 36 // Alice receives her commit 37 await group_alice.receive(commit_output.commit); 38 39 // Bob joins the group 40 let group_bob = await mls.groupJoin(bob, commit_output.welcome); 41 42 // Test: compare the group identifier after the join 43 is(byteArrayToHexString(group_alice.groupId), byteArrayToHexString(group_bob.groupId), "Alice Group ID == Bob Group ID"); 44 45 // Test: compare the group members after the join 46 let members_alice_1 = await group_alice.details(); 47 let members_bob_1 = await group_bob.details(); 48 49 // Test: the group should have exactly two members at epoch 1 50 is(members_alice_1.members.length, 2, "There should be exactly two members in the group"); 51 is(members_bob_1.members.length, 2, "There should be exactly two members in the group"); 52 53 // Test: Bob should be in the group according to Alice's view 54 is(members_alice_1.members.some(member => byteArrayToHexString(member.clientId) === byteArrayToHexString(bob.content)), true, "Bob should be in the group"); 55 56 // Test: Alice should be in the group according to Alice's view 57 is(members_alice_1.members.some(member => byteArrayToHexString(member.clientId) === byteArrayToHexString(alice.content)), true, "Alice should be in the group"); 58 59 // Test: Bob should be in the group according to Bob's view 60 is(members_bob_1.members.some(member => byteArrayToHexString(member.clientId) === byteArrayToHexString(bob.content)), true, "Bob should be in the group"); 61 62 // Test: Alice should be in the group according to Bob's view 63 is(members_bob_1.members.some(member => byteArrayToHexString(member.clientId) === byteArrayToHexString(alice.content)), true, "Alice should be in the group"); 64 // Bob closes the group 65 let commit_output_2 = await group_bob.close(); 66 67 // Info: print the commit output 68 info("Commit Output:", JSON.stringify(commit_output_2)); 69 70 // Alice receives the close of the group 71 let group_and_epoch_final_alice = await group_alice.receive(commit_output_2.commit); 72 73 // Info: print the group and epoch final alice 74 info("Group and Epoch Final Alice:", JSON.stringify(group_and_epoch_final_alice.groupIdEpoch)); 75 76 // Bob processes its close of the group 77 // This leaves Bob alone in the new epoch which is NOT 0xFF..FF 78 let group_and_epoch_final_bob = await group_bob.receive(commit_output_2.commit); 79 80 // Info: print the group and epoch final Bob 81 info("Group and Epoch Final Bob:", JSON.stringify(group_and_epoch_final_bob.groupIdEpoch)); 82 83 // Test: compare the group members after the close 84 let members_alice_2 = await group_alice.details(); 85 let members_bob_2 = await group_bob.details(); 86 87 // This is counter intuitive, but true: Alice has two members in the group 88 // after being removed by Bob, basically because she is left in her epoch. 89 // Technically she can send messages in the previous epoch, but not in the current one. 90 is(members_alice_2.members.length, 2, "Alice should have two members in the group"); 91 is(members_bob_2.members.length, 1, "Bob should be alone in the group"); 92 93 // Test: check that alice has transitioned to the 0xFF..FF epoch 94 is(byteArrayToHexString(group_and_epoch_final_alice.groupEpoch), "ffffffffffffffff", "Alice should have a returned epoch set to 0xFF..FF"); 95 96 // Test: check that bob has transitioned to epoch 2 97 const expectedEpoch = new Uint8Array(new BigUint64Array([2n]).buffer); 98 is(byteArrayToHexString(group_and_epoch_final_bob.groupEpoch), byteArrayToHexString(expectedEpoch), "Bob should have transitioned to epoch 2"); 99 100 // Bob is alone in the group and can remove its state 101 let bob_deleted = await group_bob.deleteState(); 102 103 is(bob_deleted, undefined, "Bob should have deleted his state for this group"); 104 105 SimpleTest.finish(); 106 } 107 108 SimpleTest.waitForExplicitFinish(); 109 test_group_close(); 110 111 </script> 112 </pre> 113 </body> 114 </html>