diff --git a/app/config/console.php b/app/config/console.php index 0b0d6c5881..b7a3f2195a 100644 --- a/app/config/console.php +++ b/app/config/console.php @@ -34,6 +34,11 @@ $console = [ 'legalAddress' => '', 'legalTaxId' => '', 'auths' => [ + 'membershipsUserName' => true, + 'membershipsUserEmail' => true, + 'membershipsMfa' => true, + 'membershipsUserId' => true, + 'membershipsUserPhone' => true, 'mockNumbers' => [], 'invites' => System::getEnv('_APP_CONSOLE_INVITES', 'enabled') === 'enabled', 'limit' => (System::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php index d146684a20..ef8d130855 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/Get.php @@ -70,12 +70,13 @@ class Get extends Action throw new Exception(Exception::MEMBERSHIP_NOT_FOUND); } + // Default should be "false", but existing projects already rely on this being "true" $membershipsPrivacy = [ - 'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? false, - 'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? false, - 'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? false, - 'userId' => $project->getAttribute('auths', [])['membershipsUserId'] ?? false, - 'userPhone' => $project->getAttribute('auths', [])['membershipsUserPhone'] ?? false, + 'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? true, + 'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? true, + 'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true, + 'userId' => $project->getAttribute('auths', [])['membershipsUserId'] ?? true, + 'userPhone' => $project->getAttribute('auths', [])['membershipsUserPhone'] ?? true, ]; $roles = $authorization->getRoles(); diff --git a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php index 70b78e02c6..7835c8051f 100644 --- a/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php +++ b/src/Appwrite/Platform/Modules/Teams/Http/Memberships/XList.php @@ -123,12 +123,13 @@ class XList extends Action $memberships = array_filter($memberships, fn (Document $membership) => !empty($membership->getAttribute('userId'))); + // Default should be "false", but existing projects already rely on this being "true" $membershipsPrivacy = [ - 'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? false, - 'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? false, - 'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? false, - 'userId' => $project->getAttribute('auths', [])['membershipsUserId'] ?? false, - 'userPhone' => $project->getAttribute('auths', [])['membershipsUserPhone'] ?? false, + 'userName' => $project->getAttribute('auths', [])['membershipsUserName'] ?? true, + 'userEmail' => $project->getAttribute('auths', [])['membershipsUserEmail'] ?? true, + 'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true, + 'userId' => $project->getAttribute('auths', [])['membershipsUserId'] ?? true, + 'userPhone' => $project->getAttribute('auths', [])['membershipsUserPhone'] ?? true, ]; $roles = $authorization->getRoles(); diff --git a/tests/e2e/Services/Teams/TeamsConsoleClientTest.php b/tests/e2e/Services/Teams/TeamsConsoleClientTest.php index 2a1367d749..da19a26c87 100644 --- a/tests/e2e/Services/Teams/TeamsConsoleClientTest.php +++ b/tests/e2e/Services/Teams/TeamsConsoleClientTest.php @@ -14,6 +14,65 @@ class TeamsConsoleClientTest extends Scope use ProjectConsole; use SideClient; + public function testConsoleMembershipPrivacyDefaults(): void + { + $teamData = $this->createTeamHelper(); + $membershipData = $this->createAndAcceptMembershipHelper($teamData['teamUid'], $teamData['teamName']); + + $teamUid = $teamData['teamUid']; + $projectId = $this->getProject()['$id']; + $owner = $this->getUser(); + $memberHeaders = [ + 'origin' => 'http://localhost', + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + 'cookie' => 'a_session_' . $projectId . '=' . $membershipData['session'], + ]; + + $ownerMemberships = $this->client->call(Client::METHOD_GET, '/teams/' . $teamUid . '/memberships', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $projectId, + ], $this->getHeaders())); + + $this->assertEquals(200, $ownerMemberships['headers']['status-code']); + $this->assertEquals(2, $ownerMemberships['body']['total']); + + $ownerMembershipsByUser = []; + foreach ($ownerMemberships['body']['memberships'] as $membership) { + $ownerMembershipsByUser[$membership['userId']] = $membership; + } + + $this->assertArrayHasKey($owner['$id'], $ownerMembershipsByUser); + $this->assertContains('owner', $ownerMembershipsByUser[$owner['$id']]['roles']); + + $this->assertArrayHasKey($membershipData['userUid'], $ownerMembershipsByUser); + $this->assertNotContains('owner', $ownerMembershipsByUser[$membershipData['userUid']]['roles']); + $this->assertSame($membershipData['userUid'], $ownerMembershipsByUser[$membershipData['userUid']]['userId']); + $this->assertSame($membershipData['name'], $ownerMembershipsByUser[$membershipData['userUid']]['userName']); + $this->assertSame($membershipData['email'], $ownerMembershipsByUser[$membershipData['userUid']]['userEmail']); + $this->assertFalse($ownerMembershipsByUser[$membershipData['userUid']]['mfa']); + + $memberMemberships = $this->client->call(Client::METHOD_GET, '/teams/' . $teamUid . '/memberships', $memberHeaders); + + $this->assertEquals(200, $memberMemberships['headers']['status-code']); + $this->assertEquals(2, $memberMemberships['body']['total']); + + $memberMembershipsByUser = []; + foreach ($memberMemberships['body']['memberships'] as $membership) { + $memberMembershipsByUser[$membership['userId']] = $membership; + } + + $this->assertArrayHasKey($owner['$id'], $memberMembershipsByUser); + $this->assertSame($owner['$id'], $memberMembershipsByUser[$owner['$id']]['userId']); + $this->assertSame($owner['name'], $memberMembershipsByUser[$owner['$id']]['userName']); + $this->assertSame($owner['email'], $memberMembershipsByUser[$owner['$id']]['userEmail']); + $this->assertFalse($memberMembershipsByUser[$owner['$id']]['mfa']); + $this->assertContains('owner', $memberMembershipsByUser[$owner['$id']]['roles']); + + $this->assertArrayHasKey($membershipData['userUid'], $memberMembershipsByUser); + $this->assertNotContains('owner', $memberMembershipsByUser[$membershipData['userUid']]['roles']); + } + public function testTeamCreateMembershipConsole(): void { $teamData = $this->createTeamHelper();