diff --git a/CHANGELOG.md b/CHANGELOG.md index 343d88fc..844d769b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 30.3.1 + +* Fixed: added `ProjectAuthMethodId::PASSKEY()`, so `project.updateAuthMethod` can enable passkeys +* Fixed: added `ProjectPolicyId::PASSKEY()` and the `PolicyPasskey` model, so `getPolicy` and `listPolicies` return the passkey policy + ## 30.3.0 * Added: `account` passkey methods `listPasskeys`, `createPasskey`, `getPasskey`, `updatePasskey`, `deletePasskey` and `updatePasskeyVerification` diff --git a/src/Appwrite/Client.php b/src/Appwrite/Client.php index cc275d06..3d7f3e59 100644 --- a/src/Appwrite/Client.php +++ b/src/Appwrite/Client.php @@ -43,11 +43,11 @@ class Client * */ protected array $headers = [ - 'user-agent' => 'AppwritePHPSDK/30.3.0 ()', + 'user-agent' => 'AppwritePHPSDK/30.3.1 ()', 'x-sdk-name' => 'PHP', 'x-sdk-platform' => 'server', 'x-sdk-language' => 'php', - 'x-sdk-version' => '30.3.0', + 'x-sdk-version' => '30.3.1', ]; /** diff --git a/src/Appwrite/Enums/ProjectAuthMethodId.php b/src/Appwrite/Enums/ProjectAuthMethodId.php index bd8fd7ea..07b1ed6a 100644 --- a/src/Appwrite/Enums/ProjectAuthMethodId.php +++ b/src/Appwrite/Enums/ProjectAuthMethodId.php @@ -16,6 +16,7 @@ class ProjectAuthMethodId implements JsonSerializable, Stringable private static ProjectAuthMethodId $INVITES; private static ProjectAuthMethodId $JWT; private static ProjectAuthMethodId $PHONE; + private static ProjectAuthMethodId $PASSKEY; private function __construct(private readonly string $value) { @@ -73,6 +74,12 @@ public static function PHONE(): ProjectAuthMethodId return self::$PHONE; } + public static function PASSKEY(): ProjectAuthMethodId + { + self::$PASSKEY ??= new ProjectAuthMethodId('passkey'); + + return self::$PASSKEY; + } public static function from(string $value): self { @@ -84,6 +91,7 @@ public static function from(string $value): self 'invites' => self::INVITES(), 'jwt' => self::JWT(), 'phone' => self::PHONE(), + 'passkey' => self::PASSKEY(), default => throw new \InvalidArgumentException('Unknown ProjectAuthMethodId value: ' . $value), }; } diff --git a/src/Appwrite/Enums/ProjectPolicyId.php b/src/Appwrite/Enums/ProjectPolicyId.php index 975051be..3b134d5c 100644 --- a/src/Appwrite/Enums/ProjectPolicyId.php +++ b/src/Appwrite/Enums/ProjectPolicyId.php @@ -24,6 +24,7 @@ class ProjectPolicyId implements JsonSerializable, Stringable private static ProjectPolicyId $DENYDISPOSABLEEMAIL; private static ProjectPolicyId $DENYFREEEMAIL; private static ProjectPolicyId $DENYCORPORATEEMAIL; + private static ProjectPolicyId $PASSKEY; private function __construct(private readonly string $value) { @@ -129,6 +130,12 @@ public static function DENYCORPORATEEMAIL(): ProjectPolicyId return self::$DENYCORPORATEEMAIL; } + public static function PASSKEY(): ProjectPolicyId + { + self::$PASSKEY ??= new ProjectPolicyId('passkey'); + + return self::$PASSKEY; + } public static function from(string $value): self { @@ -148,6 +155,7 @@ public static function from(string $value): self 'deny-disposable-email' => self::DENYDISPOSABLEEMAIL(), 'deny-free-email' => self::DENYFREEEMAIL(), 'deny-corporate-email' => self::DENYCORPORATEEMAIL(), + 'passkey' => self::PASSKEY(), default => throw new \InvalidArgumentException('Unknown ProjectPolicyId value: ' . $value), }; } diff --git a/src/Appwrite/Models/PolicyPasskey.php b/src/Appwrite/Models/PolicyPasskey.php new file mode 100644 index 00000000..5dd5735a --- /dev/null +++ b/src/Appwrite/Models/PolicyPasskey.php @@ -0,0 +1,63 @@ + $data + */ + public static function from(array $data): static + { + if (!array_key_exists('$id', $data)) { + throw new \InvalidArgumentException('Missing required field "$id" for ' . static::class . '.'); + } + if (!array_key_exists('rpId', $data)) { + throw new \InvalidArgumentException('Missing required field "rpId" for ' . static::class . '.'); + } + if (!array_key_exists('origins', $data)) { + throw new \InvalidArgumentException('Missing required field "origins" for ' . static::class . '.'); + } + + return new static( + id: $data['$id'], + rpId: $data['rpId'], + origins: $data['origins'] + ); + } + + /** + * @return array + */ + public function toArray(): array + { + return [ + '$id' => static::serializeValue($this->id), + 'rpId' => static::serializeValue($this->rpId), + 'origins' => static::serializeValue($this->origins) + ]; + } +} diff --git a/src/Appwrite/Services/Project.php b/src/Appwrite/Services/Project.php index 367af399..172ad2d0 100644 --- a/src/Appwrite/Services/Project.php +++ b/src/Appwrite/Services/Project.php @@ -3764,7 +3764,7 @@ public function updateUserLimitPolicy(?int $total): \Appwrite\Models\Project * * @throws AppwriteException */ - public function getPolicy(ProjectPolicyId $policyId): \Appwrite\Models\PolicyPasswordDictionary|\Appwrite\Models\PolicyPasswordHistory|\Appwrite\Models\PolicyPasswordStrength|\Appwrite\Models\PolicyPasswordPersonalData|\Appwrite\Models\PolicySessionAlert|\Appwrite\Models\PolicySessionDuration|\Appwrite\Models\PolicySessionInvalidation|\Appwrite\Models\PolicySessionLimit|\Appwrite\Models\PolicyUserLimit|\Appwrite\Models\PolicyMembershipPrivacy|\Appwrite\Models\PolicyMfaFactors|\Appwrite\Models\PolicyDenyAliasedEmail|\Appwrite\Models\PolicyDenyDisposableEmail|\Appwrite\Models\PolicyDenyFreeEmail|\Appwrite\Models\PolicyDenyCorporateEmail + public function getPolicy(ProjectPolicyId $policyId): \Appwrite\Models\PolicyPasswordDictionary|\Appwrite\Models\PolicyPasswordHistory|\Appwrite\Models\PolicyPasswordStrength|\Appwrite\Models\PolicyPasswordPersonalData|\Appwrite\Models\PolicySessionAlert|\Appwrite\Models\PolicySessionDuration|\Appwrite\Models\PolicySessionInvalidation|\Appwrite\Models\PolicySessionLimit|\Appwrite\Models\PolicyUserLimit|\Appwrite\Models\PolicyMembershipPrivacy|\Appwrite\Models\PolicyMfaFactors|\Appwrite\Models\PolicyDenyAliasedEmail|\Appwrite\Models\PolicyDenyDisposableEmail|\Appwrite\Models\PolicyDenyFreeEmail|\Appwrite\Models\PolicyDenyCorporateEmail|\Appwrite\Models\PolicyPasskey { $apiPath = str_replace( ['{policyId}'], @@ -3850,6 +3850,10 @@ public function getPolicy(ProjectPolicyId $policyId): \Appwrite\Models\PolicyPas return \Appwrite\Models\PolicyDenyCorporateEmail::from($response); } + if (($response['$id'] ?? null) === 'passkey') { + return \Appwrite\Models\PolicyPasskey::from($response); + } + throw new \UnexpectedValueException('Unable to match response to any expected response model.'); } diff --git a/tests/Appwrite/Services/ProjectTest.php b/tests/Appwrite/Services/ProjectTest.php index 80ad0824..620addb8 100644 --- a/tests/Appwrite/Services/ProjectTest.php +++ b/tests/Appwrite/Services/ProjectTest.php @@ -3208,10 +3208,11 @@ public function testMethodGetPolicy(): void $data = array_replace( [ "\$id" => "password-dictionary", - "enabled" => true + "rpId" => "example.com", + "origins" => [] ], [ - "\$id" => "deny-corporate-email" + "\$id" => "passkey" ] ); @@ -3226,7 +3227,7 @@ public function testMethodGetPolicy(): void ProjectPolicyId::PASSWORDDICTIONARY() ); - $this->assertInstanceOf(\Appwrite\Models\PolicyDenyCorporateEmail::class, $response); + $this->assertInstanceOf(\Appwrite\Models\PolicyPasskey::class, $response); } public function testMethodUpdateProtocol(): void {