diff --git a/README.md b/README.md
index ca9e5404..5b791018 100644
--- a/README.md
+++ b/README.md
@@ -138,9 +138,9 @@ string emailAddressOrErrorMessage = userResponse.Result.Match(
```
## ⌛ Progress
-![Server & Client - 62 / 291](https://img.shields.io/badge/Server_&_Client-62%20%2F%20291-red?style=for-the-badge)
+![Server & Client - 63 / 291](https://img.shields.io/badge/Server_&_Client-63%20%2F%20291-red?style=for-the-badge)
-![Server - 18 / 201](https://img.shields.io/badge/Server-18%20%2F%20201-red?style=for-the-badge)
+![Server - 19 / 201](https://img.shields.io/badge/Server-19%20%2F%20201-red?style=for-the-badge)
![Client - 44 / 90](https://img.shields.io/badge/Client-44%20%2F%2090-gold?style=for-the-badge)
@@ -205,7 +205,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match(
| [Create Phone Verification (Confirmation)](https://appwrite.io/docs/references/1.6.x/client-rest/account#updatePhoneVerification) | ✅ | ❌ | |
### Users
-![Account - 7 / 41](https://img.shields.io/badge/Users-7%20%2F%2041-red?style=for-the-badge)
+![Account - 8 / 41](https://img.shields.io/badge/Users-8%20%2F%2041-red?style=for-the-badge)
| Endpoint | Client | Server |
|:-:|:-:|:-:|
@@ -216,7 +216,7 @@ string emailAddressOrErrorMessage = userResponse.Result.Match(
| [List Identities](https://appwrite.io/docs/references/1.6.x/server-rest/users#listIdentities) | ❌ | ✅ |
| [Delete Identity](https://appwrite.io/docs/references/1.6.x/server-rest/users#deleteIdentity) | ❌ | ✅ |
| [Create User with MD5 Password](https://appwrite.io/docs/references/1.6.x/server-rest/users#createMD5User) | ❌ | ✅ |
-| [Create User with PHPass Password](https://appwrite.io/docs/references/1.6.x/server-rest/users#createPHPassUser) | ❌ | ⬛ |
+| [Create User with PHPass Password](https://appwrite.io/docs/references/1.6.x/server-rest/users#createPHPassUser) | ❌ | ✅ |
| [Create User with Scrypt Password](https://appwrite.io/docs/references/1.6.x/server-rest/users#createScryptUser) | ❌ | ⬛ |
| [Create User with Scrypt Modified Password](https://appwrite.io/docs/references/1.6.x/server-rest/users#createScryptModifiedUser) | ❌ | ⬛ |
| [Create User with SHA Password](https://appwrite.io/docs/references/1.6.x/server-rest/users#createSHAUser) | ❌ | ⬛ |
diff --git a/src/PinguApps.Appwrite.Playground/App.cs b/src/PinguApps.Appwrite.Playground/App.cs
index 04cf37c4..5545aaa3 100644
--- a/src/PinguApps.Appwrite.Playground/App.cs
+++ b/src/PinguApps.Appwrite.Playground/App.cs
@@ -17,13 +17,13 @@ public App(Client.IAppwriteClient client, Server.Clients.IAppwriteClient server,
public async Task Run(string[] args)
{
- var request = new CreateUserWithMd5PasswordRequest()
+ var request = new CreateUserWithPhpassPasswordRequest()
{
Email = "pingu@example.com",
- Password = "34819d7beeabb9260a5c854bc85b3e44"
+ Password = "$P$5ZDzPE45Ci.QxPaPz.03z6TYbakcSQ0"
};
- var response = await _server.Users.CreateUserWithMd5Password(request);
+ var response = await _server.Users.CreateUserWithPhpassPassword(request);
Console.WriteLine(response.Result.Match(
result => result.ToString(),
diff --git a/src/PinguApps.Appwrite.Server/Clients/IUsersClient.cs b/src/PinguApps.Appwrite.Server/Clients/IUsersClient.cs
index ae23124b..475fe6ef 100644
--- a/src/PinguApps.Appwrite.Server/Clients/IUsersClient.cs
+++ b/src/PinguApps.Appwrite.Server/Clients/IUsersClient.cs
@@ -68,7 +68,13 @@ public interface IUsersClient
/// The request content
/// The user
Task> CreateUserWithMd5Password(CreateUserWithMd5PasswordRequest request);
- [Obsolete("This method hasn't yet been implemented.", true)]
+
+ ///
+ /// Create a new user. Password provided must be hashed with the PHPass algorithm. Use to create users with a plain text password.
+ /// Appwrite Docs
+ ///
+ /// The request content
+ /// The user
Task> CreateUserWithPhpassPassword(CreateUserWithPhpassPasswordRequest request);
[Obsolete("This method hasn't yet been implemented.", true)]
Task> CreateUserWithScryptPassword(CreateUserWithScryptPasswordRequest request);
diff --git a/src/PinguApps.Appwrite.Server/Clients/UsersClient.cs b/src/PinguApps.Appwrite.Server/Clients/UsersClient.cs
index 4fe660fe..b75a4e44 100644
--- a/src/PinguApps.Appwrite.Server/Clients/UsersClient.cs
+++ b/src/PinguApps.Appwrite.Server/Clients/UsersClient.cs
@@ -145,9 +145,22 @@ public async Task> CreateUserWithMd5Password(CreateUserWith
}
}
- [ExcludeFromCodeCoverage]
///
- public Task> CreateUserWithPhpassPassword(CreateUserWithPhpassPasswordRequest request) => throw new NotImplementedException();
+ public async Task> CreateUserWithPhpassPassword(CreateUserWithPhpassPasswordRequest request)
+ {
+ try
+ {
+ request.Validate(true);
+
+ var result = await _usersApi.CreateUserWithPhpassPassword(request);
+
+ return result.GetApiResponse();
+ }
+ catch (Exception e)
+ {
+ return e.GetExceptionResponse();
+ }
+ }
[ExcludeFromCodeCoverage]
///
diff --git a/tests/PinguApps.Appwrite.Server.Tests/Clients/Users/UsersClientTests.CreateUserWithPhpassPassword.cs b/tests/PinguApps.Appwrite.Server.Tests/Clients/Users/UsersClientTests.CreateUserWithPhpassPassword.cs
new file mode 100644
index 00000000..32e7f401
--- /dev/null
+++ b/tests/PinguApps.Appwrite.Server.Tests/Clients/Users/UsersClientTests.CreateUserWithPhpassPassword.cs
@@ -0,0 +1,77 @@
+using System.Net;
+using PinguApps.Appwrite.Shared.Requests.Users;
+using PinguApps.Appwrite.Shared.Tests;
+using RichardSzalay.MockHttp;
+
+namespace PinguApps.Appwrite.Server.Tests.Clients.Users;
+public partial class UsersClientTests
+{
+ [Fact]
+ public async Task CreateUserWithPhpassPassword_ShouldReturnSuccess_WhenApiCallSucceeds()
+ {
+ // Arrange
+ var request = new CreateUserWithPhpassPasswordRequest
+ {
+ Email = "test@example.com",
+ Password = "password123"
+ };
+
+ _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/users/phpass")
+ .WithJsonContent(request)
+ .ExpectedHeaders()
+ .Respond(Constants.AppJson, Constants.UserResponse);
+
+ // Act
+ var result = await _appwriteClient.Users.CreateUserWithPhpassPassword(request);
+
+ // Assert
+ Assert.True(result.Success);
+ }
+
+ [Fact]
+ public async Task CreateUserWithPhpassPassword_ShouldHandleException_WhenApiCallFails()
+ {
+ // Arrange
+ var request = new CreateUserWithPhpassPasswordRequest
+ {
+ Email = "test@example.com",
+ Password = "password123"
+ };
+
+ _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/users/phpass")
+ .WithJsonContent(request)
+ .ExpectedHeaders()
+ .Respond(HttpStatusCode.BadRequest, Constants.AppJson, Constants.AppwriteError);
+
+ // Act
+ var result = await _appwriteClient.Users.CreateUserWithPhpassPassword(request);
+
+ // Assert
+ Assert.True(result.IsError);
+ Assert.True(result.IsAppwriteError);
+ }
+
+ [Fact]
+ public async Task CreateUserWithPhpassPassword_ShouldReturnErrorResponse_WhenExceptionOccurs()
+ {
+ // Arrange
+ var request = new CreateUserWithPhpassPasswordRequest
+ {
+ Email = "test@example.com",
+ Password = "password123"
+ };
+
+ _mockHttp.Expect(HttpMethod.Post, $"{Constants.Endpoint}/users/phpass")
+ .WithJsonContent(request)
+ .ExpectedHeaders()
+ .Throw(new HttpRequestException("An error occurred"));
+
+ // Act
+ var result = await _appwriteClient.Users.CreateUserWithPhpassPassword(request);
+
+ // Assert
+ Assert.False(result.Success);
+ Assert.True(result.IsInternalError);
+ Assert.Equal("An error occurred", result.Result.AsT2.Message);
+ }
+}