From 8504188d7634ee6d11912cb4deee3e46ded33746 Mon Sep 17 00:00:00 2001 From: Isla <5048549+islathehut@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:24:03 -0400 Subject: [PATCH 1/2] Skip assigning member role on connection when user doesn't have role but does have role marker --- packages/auth/src/connection/Connection.ts | 11 +++++-- .../connection/test/authentication.test.ts | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/packages/auth/src/connection/Connection.ts b/packages/auth/src/connection/Connection.ts index 8405cf0af..d01ad5f1a 100644 --- a/packages/auth/src/connection/Connection.ts +++ b/packages/auth/src/connection/Connection.ts @@ -325,9 +325,16 @@ export class Connection extends EventEmitter { assert(roles) assert(userId) - if (!roles!.includes(MEMBER) && context.server == null && !team!.hasServer(userId!)) { - team!.addMemberRole(userId!, MEMBER) + const hasMemberMarker = team.memberHasRoleMarker(userId, MEMBER) + const hasMemberRole = team.memberHasRole(userId, MEMBER) + this.logger.debug('has member role?', hasMemberMarker, hasMemberRole, roles) + if (!hasMemberRole && (hasMemberMarker || roles.includes(MEMBER))) { + this.logger.warn(`Peer had marker for ${MEMBER} but lacked the appropriate lockboxes, this may be malicious or we are missing syncable data`) + } else if (!hasMemberRole && !roles.includes(MEMBER) && context.server == null && !team.hasServer(userId)) { + this.logger.debug(`Assigning ${MEMBER} role to peer`) + team.addMemberRole(userId, MEMBER) } + this.#queueMessage('ACCEPT_IDENTITY') }, diff --git a/packages/auth/src/connection/test/authentication.test.ts b/packages/auth/src/connection/test/authentication.test.ts index 2a5db0e45..848cbbe80 100644 --- a/packages/auth/src/connection/test/authentication.test.ts +++ b/packages/auth/src/connection/test/authentication.test.ts @@ -31,6 +31,36 @@ describe('connection', () => { await disconnect(alice, bob) }) + it('connects two members and assigns member role', async () => { + const { alice, bob } = setup('alice', { user: 'bob', admin: false, member: false, addToTeam: true }) + + // đŸ‘©đŸŸ đŸ‘šđŸ»â€đŸŠČ Alice and Bob both join the channel + await connect(alice, bob) + + // đŸ‘©đŸŸ đŸ‘šđŸ»â€đŸŠČ Alice and Bob both leave the channel + await disconnect(alice, bob) + + expect(alice.team.memberHasRole(bob.userId, MEMBER)).toBe(true) + expect(bob.team.memberHasRole(bob.userId, MEMBER)).toBe(true) + }) + + it(`connects two members and doesn't assign member role when marker exists but no lockboxes`, async () => { + const { alice, bob } = setup('alice', { user: 'bob', admin: false, member: false, rolesWithoutLockboxes: [MEMBER] }) + expect(alice.team.memberHasRole(bob.userId, MEMBER)).toBe(false) + expect(bob.team.memberHasRole(bob.userId, MEMBER)).toBe(false) + expect(alice.team.memberHasRoleMarker(bob.userId, MEMBER)).toBe(true) + expect(bob.team.memberHasRoleMarker(bob.userId, MEMBER)).toBe(true) + + // đŸ‘©đŸŸ đŸ‘šđŸ»â€đŸŠČ Alice and Bob both join the channel + await connect(alice, bob) + + // đŸ‘©đŸŸ đŸ‘šđŸ»â€đŸŠČ Alice and Bob both leave the channel + await disconnect(alice, bob) + + expect(alice.team.memberHasRole(bob.userId, MEMBER)).toBe(false) + expect(bob.team.memberHasRole(bob.userId, MEMBER)).toBe(false) + }) + it("doesn't connect with a member who has been removed", async () => { const { alice, bob } = setup('alice', 'bob') From 062575fc29987dc0c82a1aa34d02d31390a4b21e Mon Sep 17 00:00:00 2001 From: Isla <5048549+islathehut@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:28:38 -0400 Subject: [PATCH 2/2] Remove testing log --- packages/auth/src/connection/Connection.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/auth/src/connection/Connection.ts b/packages/auth/src/connection/Connection.ts index d01ad5f1a..4d58d43c2 100644 --- a/packages/auth/src/connection/Connection.ts +++ b/packages/auth/src/connection/Connection.ts @@ -327,7 +327,6 @@ export class Connection extends EventEmitter { const hasMemberMarker = team.memberHasRoleMarker(userId, MEMBER) const hasMemberRole = team.memberHasRole(userId, MEMBER) - this.logger.debug('has member role?', hasMemberMarker, hasMemberRole, roles) if (!hasMemberRole && (hasMemberMarker || roles.includes(MEMBER))) { this.logger.warn(`Peer had marker for ${MEMBER} but lacked the appropriate lockboxes, this may be malicious or we are missing syncable data`) } else if (!hasMemberRole && !roles.includes(MEMBER) && context.server == null && !team.hasServer(userId)) {