updatePasswordDictionaryPolicy(true); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(true, $response['body']['authPasswordDictionary']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(true, $project['body']['authPasswordDictionary']); // Cleanup $this->updatePasswordDictionaryPolicy(false); } public function testUpdatePasswordDictionaryPolicyDisable(): void { $this->updatePasswordDictionaryPolicy(true); $response = $this->updatePasswordDictionaryPolicy(false); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authPasswordDictionary']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(false, $project['body']['authPasswordDictionary']); } public function testUpdatePasswordDictionaryPolicyIdempotent(): void { $first = $this->updatePasswordDictionaryPolicy(true); $this->assertSame(200, $first['headers']['status-code']); $this->assertSame(true, $first['body']['authPasswordDictionary']); $second = $this->updatePasswordDictionaryPolicy(true); $this->assertSame(200, $second['headers']['status-code']); $this->assertSame(true, $second['body']['authPasswordDictionary']); // Cleanup $this->updatePasswordDictionaryPolicy(false); } public function testUpdatePasswordDictionaryPolicyWithoutAuth(): void { $response = $this->updatePasswordDictionaryPolicy(true, false); $this->assertSame(401, $response['headers']['status-code']); } public function testUpdatePasswordDictionaryPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/password-dictionary', $this->buildHeaders(), [ 'enabled' => 'not-a-boolean', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordDictionaryPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/password-dictionary', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } // ========================================================================= // Password History Policy // ========================================================================= public function testUpdatePasswordHistoryPolicyEnable(): void { $response = $this->updatePasswordHistoryPolicy(5); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(5, $response['body']['authPasswordHistory']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(5, $project['body']['authPasswordHistory']); // Cleanup (disable by setting total to null which maps to 0) $this->updatePasswordHistoryPolicy(null); } public function testUpdatePasswordHistoryPolicyMin(): void { $response = $this->updatePasswordHistoryPolicy(1); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(1, $response['body']['authPasswordHistory']); // Cleanup $this->updatePasswordHistoryPolicy(null); } public function testUpdatePasswordHistoryPolicyMax(): void { $response = $this->updatePasswordHistoryPolicy(5000); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(5000, $response['body']['authPasswordHistory']); // Cleanup $this->updatePasswordHistoryPolicy(null); } public function testUpdatePasswordHistoryPolicyDisable(): void { $this->updatePasswordHistoryPolicy(5); $response = $this->updatePasswordHistoryPolicy(null); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(0, $response['body']['authPasswordHistory']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(0, $project['body']['authPasswordHistory']); } public function testUpdatePasswordHistoryPolicyBelowMin(): void { $response = $this->updatePasswordHistoryPolicy(0); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordHistoryPolicyAboveMax(): void { $response = $this->updatePasswordHistoryPolicy(5001); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordHistoryPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/password-history', $this->buildHeaders(), [ 'total' => 'not-a-number', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordHistoryPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/password-history', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordHistoryPolicyWithoutAuth(): void { $response = $this->updatePasswordHistoryPolicy(5, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Password Personal Data Policy // ========================================================================= public function testUpdatePasswordPersonalDataPolicyEnable(): void { $response = $this->updatePasswordPersonalDataPolicy(true); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(true, $response['body']['authPersonalDataCheck']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(true, $project['body']['authPersonalDataCheck']); // Cleanup $this->updatePasswordPersonalDataPolicy(false); } public function testUpdatePasswordPersonalDataPolicyDisable(): void { $this->updatePasswordPersonalDataPolicy(true); $response = $this->updatePasswordPersonalDataPolicy(false); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authPersonalDataCheck']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(false, $project['body']['authPersonalDataCheck']); } public function testUpdatePasswordPersonalDataPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/password-personal-data', $this->buildHeaders(), [ 'enabled' => 'not-a-boolean', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordPersonalDataPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/password-personal-data', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdatePasswordPersonalDataPolicyWithoutAuth(): void { $response = $this->updatePasswordPersonalDataPolicy(true, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Session Alert Policy // ========================================================================= public function testUpdateSessionAlertPolicyEnable(): void { $response = $this->updateSessionAlertPolicy(true); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(true, $response['body']['authSessionAlerts']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(true, $project['body']['authSessionAlerts']); // Cleanup $this->updateSessionAlertPolicy(false); } public function testUpdateSessionAlertPolicyDisable(): void { $this->updateSessionAlertPolicy(true); $response = $this->updateSessionAlertPolicy(false); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authSessionAlerts']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(false, $project['body']['authSessionAlerts']); } public function testUpdateSessionAlertPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-alert', $this->buildHeaders(), [ 'enabled' => 'not-a-boolean', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionAlertPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-alert', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionAlertPolicyWithoutAuth(): void { $response = $this->updateSessionAlertPolicy(true, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Session Duration Policy // ========================================================================= public function testUpdateSessionDurationPolicy(): void { $response = $this->updateSessionDurationPolicy(3600); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(3600, $response['body']['authDuration']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(3600, $project['body']['authDuration']); // Cleanup (reset to default 1 year) $this->updateSessionDurationPolicy(31536000); } public function testUpdateSessionDurationPolicyMin(): void { $response = $this->updateSessionDurationPolicy(5); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(5, $response['body']['authDuration']); // Cleanup $this->updateSessionDurationPolicy(31536000); } public function testUpdateSessionDurationPolicyMax(): void { $response = $this->updateSessionDurationPolicy(31536000); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(31536000, $response['body']['authDuration']); } public function testUpdateSessionDurationPolicyBelowMin(): void { $response = $this->updateSessionDurationPolicy(4); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionDurationPolicyAboveMax(): void { $response = $this->updateSessionDurationPolicy(31536001); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionDurationPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-duration', $this->buildHeaders(), [ 'duration' => 'not-a-number', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionDurationPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-duration', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionDurationPolicyWithoutAuth(): void { $response = $this->updateSessionDurationPolicy(3600, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Session Invalidation Policy // ========================================================================= public function testUpdateSessionInvalidationPolicyEnable(): void { $response = $this->updateSessionInvalidationPolicy(true); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(true, $response['body']['authInvalidateSessions']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(true, $project['body']['authInvalidateSessions']); // Cleanup $this->updateSessionInvalidationPolicy(false); } public function testUpdateSessionInvalidationPolicyDisable(): void { $this->updateSessionInvalidationPolicy(true); $response = $this->updateSessionInvalidationPolicy(false); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authInvalidateSessions']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(false, $project['body']['authInvalidateSessions']); } public function testUpdateSessionInvalidationPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-invalidation', $this->buildHeaders(), [ 'enabled' => 'not-a-boolean', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionInvalidationPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-invalidation', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionInvalidationPolicyWithoutAuth(): void { $response = $this->updateSessionInvalidationPolicy(true, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Session Limit Policy // ========================================================================= public function testUpdateSessionLimitPolicy(): void { $response = $this->updateSessionLimitPolicy(5); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(5, $response['body']['authSessionsLimit']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(5, $project['body']['authSessionsLimit']); // Cleanup (reset to default) $this->updateSessionLimitPolicy(10); } public function testUpdateSessionLimitPolicyMin(): void { $response = $this->updateSessionLimitPolicy(1); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(1, $response['body']['authSessionsLimit']); // Cleanup $this->updateSessionLimitPolicy(10); } public function testUpdateSessionLimitPolicyMax(): void { $response = $this->updateSessionLimitPolicy(5000); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(5000, $response['body']['authSessionsLimit']); // Cleanup $this->updateSessionLimitPolicy(10); } public function testUpdateSessionLimitPolicyDisable(): void { $response = $this->updateSessionLimitPolicy(null); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(0, $response['body']['authSessionsLimit']); // Cleanup $this->updateSessionLimitPolicy(10); } public function testUpdateSessionLimitPolicyBelowMin(): void { $response = $this->updateSessionLimitPolicy(0); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionLimitPolicyAboveMax(): void { $response = $this->updateSessionLimitPolicy(5001); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionLimitPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-limit', $this->buildHeaders(), [ 'total' => 'not-a-number', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionLimitPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/session-limit', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateSessionLimitPolicyWithoutAuth(): void { $response = $this->updateSessionLimitPolicy(5, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // User Limit Policy // ========================================================================= public function testUpdateUserLimitPolicy(): void { $response = $this->updateUserLimitPolicy(100); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(100, $response['body']['authLimit']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(100, $project['body']['authLimit']); // Cleanup $this->updateUserLimitPolicy(null); } public function testUpdateUserLimitPolicyMin(): void { $response = $this->updateUserLimitPolicy(1); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(1, $response['body']['authLimit']); // Cleanup $this->updateUserLimitPolicy(null); } public function testUpdateUserLimitPolicyMax(): void { $response = $this->updateUserLimitPolicy(5000); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(5000, $response['body']['authLimit']); // Cleanup $this->updateUserLimitPolicy(null); } public function testUpdateUserLimitPolicyDisable(): void { $this->updateUserLimitPolicy(100); $response = $this->updateUserLimitPolicy(null); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(0, $response['body']['authLimit']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(0, $project['body']['authLimit']); } public function testUpdateUserLimitPolicyBelowMin(): void { $response = $this->updateUserLimitPolicy(0); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateUserLimitPolicyAboveMax(): void { $response = $this->updateUserLimitPolicy(5001); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateUserLimitPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/user-limit', $this->buildHeaders(), [ 'total' => 'not-a-number', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateUserLimitPolicyMissingParam(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/user-limit', $this->buildHeaders(), []); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateUserLimitPolicyWithoutAuth(): void { $response = $this->updateUserLimitPolicy(100, false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Membership Privacy Policy // ========================================================================= public function testUpdateMembershipPrivacyPolicyAllEnabled(): void { $response = $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); $this->assertSame(200, $response['headers']['status-code']); $this->assertNotEmpty($response['body']['$id']); $this->assertSame(true, $response['body']['authMembershipsUserId']); $this->assertSame(true, $response['body']['authMembershipsUserEmail']); $this->assertSame(true, $response['body']['authMembershipsUserPhone']); $this->assertSame(true, $response['body']['authMembershipsUserName']); $this->assertSame(true, $response['body']['authMembershipsMfa']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(true, $project['body']['authMembershipsUserId']); $this->assertSame(true, $project['body']['authMembershipsUserEmail']); $this->assertSame(true, $project['body']['authMembershipsUserPhone']); $this->assertSame(true, $project['body']['authMembershipsUserName']); $this->assertSame(true, $project['body']['authMembershipsMfa']); } public function testUpdateMembershipPrivacyPolicyAllDisabled(): void { $response = $this->updateMembershipPrivacyPolicy([ 'userId' => false, 'userEmail' => false, 'userPhone' => false, 'userName' => false, 'userMFA' => false, ]); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authMembershipsUserId']); $this->assertSame(false, $response['body']['authMembershipsUserEmail']); $this->assertSame(false, $response['body']['authMembershipsUserPhone']); $this->assertSame(false, $response['body']['authMembershipsUserName']); $this->assertSame(false, $response['body']['authMembershipsMfa']); $project = $this->getProjectDocument(); $this->assertSame(200, $project['headers']['status-code']); $this->assertSame(false, $project['body']['authMembershipsUserId']); $this->assertSame(false, $project['body']['authMembershipsUserEmail']); $this->assertSame(false, $project['body']['authMembershipsUserPhone']); $this->assertSame(false, $project['body']['authMembershipsUserName']); $this->assertSame(false, $project['body']['authMembershipsMfa']); // Cleanup (restore defaults) $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); } public function testUpdateMembershipPrivacyPolicyMixed(): void { $response = $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => false, 'userPhone' => true, 'userName' => false, 'userMFA' => true, ]); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(true, $response['body']['authMembershipsUserId']); $this->assertSame(false, $response['body']['authMembershipsUserEmail']); $this->assertSame(true, $response['body']['authMembershipsUserPhone']); $this->assertSame(false, $response['body']['authMembershipsUserName']); $this->assertSame(true, $response['body']['authMembershipsMfa']); // Cleanup $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); } public function testUpdateMembershipPrivacyPolicyIndividualFields(): void { // Start from a known baseline where every field is enabled $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); $fields = [ 'userId' => 'authMembershipsUserId', 'userEmail' => 'authMembershipsUserEmail', 'userPhone' => 'authMembershipsUserPhone', 'userName' => 'authMembershipsUserName', 'userMFA' => 'authMembershipsMfa', ]; // Each field can be toggled individually without clobbering the others foreach ($fields as $param => $attribute) { $response = $this->updateMembershipPrivacyPolicy([$param => false]); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body'][$attribute]); foreach ($fields as $otherParam => $otherAttribute) { if ($otherParam === $param) { continue; } $this->assertSame(true, $response['body'][$otherAttribute], $otherAttribute . ' should be untouched while only ' . $param . ' was updated'); } // Restore the field before the next iteration $restore = $this->updateMembershipPrivacyPolicy([$param => true]); $this->assertSame(200, $restore['headers']['status-code']); $this->assertSame(true, $restore['body'][$attribute]); } } public function testUpdateMembershipPrivacyPolicyMultipleFields(): void { $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); $response = $this->updateMembershipPrivacyPolicy([ 'userId' => false, 'userPhone' => false, ]); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authMembershipsUserId']); $this->assertSame(false, $response['body']['authMembershipsUserPhone']); $this->assertSame(true, $response['body']['authMembershipsUserEmail']); $this->assertSame(true, $response['body']['authMembershipsUserName']); $this->assertSame(true, $response['body']['authMembershipsMfa']); // Cleanup $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); } public function testUpdateMembershipPrivacyPolicyEmptyBody(): void { // PATCH with no fields should be a no-op, leaving state unchanged $this->updateMembershipPrivacyPolicy([ 'userId' => false, 'userEmail' => false, 'userPhone' => false, 'userName' => false, 'userMFA' => false, ]); $response = $this->updateMembershipPrivacyPolicy([]); $this->assertSame(200, $response['headers']['status-code']); $this->assertSame(false, $response['body']['authMembershipsUserId']); $this->assertSame(false, $response['body']['authMembershipsUserEmail']); $this->assertSame(false, $response['body']['authMembershipsUserPhone']); $this->assertSame(false, $response['body']['authMembershipsUserName']); $this->assertSame(false, $response['body']['authMembershipsMfa']); // Cleanup $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ]); } public function testUpdateMembershipPrivacyPolicyInvalidType(): void { $response = $this->client->call(Client::METHOD_PATCH, '/project/policies/membership-privacy', $this->buildHeaders(), [ 'userId' => 'not-a-boolean', ]); $this->assertSame(400, $response['headers']['status-code']); } public function testUpdateMembershipPrivacyPolicyWithoutAuth(): void { $response = $this->updateMembershipPrivacyPolicy([ 'userId' => true, 'userEmail' => true, 'userPhone' => true, 'userName' => true, 'userMFA' => true, ], false); $this->assertSame(401, $response['headers']['status-code']); } // ========================================================================= // Helpers // ========================================================================= protected function buildHeaders(bool $authenticated = true): array { $headers = [ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ]; if ($authenticated) { $headers = array_merge($headers, $this->getHeaders()); } return $headers; } protected function getProjectDocument(): array { return $this->client->call(Client::METHOD_GET, '/projects/' . $this->getProject()['$id'], [ 'content-type' => 'application/json', 'x-appwrite-project' => 'console', 'cookie' => 'a_session_console=' . $this->getRoot()['session'], ]); } protected function updatePasswordDictionaryPolicy(bool $enabled, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/password-dictionary', $this->buildHeaders($authenticated), [ 'enabled' => $enabled, ]); } protected function updatePasswordHistoryPolicy(?int $total, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/password-history', $this->buildHeaders($authenticated), [ 'total' => $total, ]); } protected function updatePasswordPersonalDataPolicy(bool $enabled, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/password-personal-data', $this->buildHeaders($authenticated), [ 'enabled' => $enabled, ]); } protected function updateSessionAlertPolicy(bool $enabled, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/session-alert', $this->buildHeaders($authenticated), [ 'enabled' => $enabled, ]); } protected function updateSessionDurationPolicy(int $duration, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/session-duration', $this->buildHeaders($authenticated), [ 'duration' => $duration, ]); } protected function updateSessionInvalidationPolicy(bool $enabled, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/session-invalidation', $this->buildHeaders($authenticated), [ 'enabled' => $enabled, ]); } protected function updateSessionLimitPolicy(?int $total, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/session-limit', $this->buildHeaders($authenticated), [ 'total' => $total, ]); } protected function updateUserLimitPolicy(?int $total, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/user-limit', $this->buildHeaders($authenticated), [ 'total' => $total, ]); } /** * @param array $params */ protected function updateMembershipPrivacyPolicy(array $params, bool $authenticated = true): mixed { return $this->client->call(Client::METHOD_PATCH, '/project/policies/membership-privacy', $this->buildHeaders($authenticated), $params); } }