Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Change Log

## 25.1.0

* Added: Email metadata fields to `User` (`emailCanonical`, `emailIsFree`, `emailIsDisposable`, `emailIsCorporate`, `emailIsCanonical`).
* Added: `Membership.userAccessedAt` field.
* Updated: Requests now send an explicit `accept` header matching each endpoint's response type.

## 25.0.0

* Breaking: `avatars.getScreenshot` `theme` parameter now uses the `BrowserTheme` enum
* Breaking: Removed generic type parameters from `presences` service methods
* Added: `BrowserTheme` enum
* Replaced: `BrowserTheme` enum
* Updated: `Presence` model is now concrete and adds a `metadata` field

## 24.1.1
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ repositories {
Next, add the dependency to your project's `build.gradle(.kts)` file:

```groovy
implementation("io.appwrite:sdk-for-android:25.0.0")
implementation("io.appwrite:sdk-for-android:25.1.0")
```

### Maven
Expand All @@ -49,7 +49,7 @@ Add this to your project's `pom.xml` file:
<dependency>
<groupId>io.appwrite</groupId>
<artifactId>sdk-for-android</artifactId>
<version>25.0.0</version>
<version>25.1.0</version>
</dependency>
</dependencies>
```
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/java/account/update-password.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Account account = new Account(client);

account.updatePassword(
"", // password
"password", // oldPassword (optional)
"<OLD_PASSWORD>", // oldPassword (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/kotlin/account/update-password.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ val account = Account(client)

val result = account.updatePassword(
password = "",
oldPassword = "password", // (optional)
oldPassword = "<OLD_PASSWORD>", // (optional)
)
```
8 changes: 5 additions & 3 deletions library/src/main/java/io/appwrite/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Client @JvmOverloads constructor(
"x-sdk-name" to "Android",
"x-sdk-platform" to "client",
"x-sdk-language" to "android",
"x-sdk-version" to "25.0.0",
"x-sdk-version" to "25.1.0",
"x-appwrite-response-format" to "1.9.5"
)
config = mutableMapOf()
Expand All @@ -113,7 +113,6 @@ class Client @JvmOverloads constructor(
*/
fun setProject(value: String): Client {
config["project"] = value
addHeader("x-appwrite-project", value)
return this
}

Expand Down Expand Up @@ -366,7 +365,10 @@ class Client @JvmOverloads constructor(
suspend fun ping(): String {
val apiPath = "/ping"
val apiParams = mutableMapOf<String, Any?>()
val apiHeaders = mutableMapOf("content-type" to "application/json")
val apiHeaders = mutableMapOf(
"content-type" to "application/json",
"X-Appwrite-Project" to config["project"].orEmpty(),
)

return call(
"GET",
Expand Down
8 changes: 8 additions & 0 deletions library/src/main/java/io/appwrite/models/Membership.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ data class Membership(
@SerializedName("mfa")
val mfa: Boolean,

/**
* Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console.
*/
@SerializedName("userAccessedAt")
val userAccessedAt: String,
Comment on lines +88 to +92

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Declare the field as nullable and use safe casting to avoid a crash when the server omits this key.

Suggested change
/**
* Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console.
*/
@SerializedName("userAccessedAt")
val userAccessedAt: String,
/**
* Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console.
*/
@SerializedName("userAccessedAt")
val userAccessedAt: String?,

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


/**
* User list of roles
*/
Expand All @@ -106,6 +112,7 @@ data class Membership(
"joined" to joined as Any,
"confirm" to confirm as Any,
"mfa" to mfa as Any,
"userAccessedAt" to userAccessedAt as Any,
"roles" to roles as Any,
)

Expand All @@ -128,6 +135,7 @@ data class Membership(
joined = map["joined"] as String,
confirm = map["confirm"] as Boolean,
mfa = map["mfa"] as Boolean,
userAccessedAt = map["userAccessedAt"] as String,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Use safe cast to match the nullable type and avoid a TypeCastException when the key is absent from the response map.

Suggested change
userAccessedAt = map["userAccessedAt"] as String,
userAccessedAt = map["userAccessedAt"] as? String,

roles = map["roles"] as List<String>,
)
}
Expand Down
50 changes: 50 additions & 0 deletions library/src/main/java/io/appwrite/models/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,36 @@ data class User<T>(
@SerializedName("emailVerification")
val emailVerification: Boolean,

/**
* Canonical form of the user email address.
*/
@SerializedName("emailCanonical")
var emailCanonical: String?,

/**
* Whether the user email is from a free email provider.
*/
@SerializedName("emailIsFree")
var emailIsFree: Boolean?,

/**
* Whether the user email is from a disposable email provider.
*/
Comment on lines +94 to +108

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 var used for model fields that should be immutable

The five new email fields (emailCanonical, emailIsFree, emailIsDisposable, emailIsCorporate, emailIsCanonical) are declared as var while every other field in User is val. These are server-returned response values that should not be mutated after construction. The same inconsistency also appears in AppSecret.lastAccessedAt and AppSecretPlaintext.lastAccessedAt in this PR. Using var allows callers to silently overwrite deserialized state, which can lead to stale or incorrect data being observed.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@SerializedName("emailIsDisposable")
var emailIsDisposable: Boolean?,

/**
* Whether the user email is from a corporate domain.
*/
@SerializedName("emailIsCorporate")
var emailIsCorporate: Boolean?,

/**
* Whether the user email is in its canonical form.
*/
@SerializedName("emailIsCanonical")
var emailIsCanonical: Boolean?,

/**
* Phone verification status.
*/
Expand Down Expand Up @@ -149,6 +179,11 @@ data class User<T>(
"email" to email as Any,
"phone" to phone as Any,
"emailVerification" to emailVerification as Any,
"emailCanonical" to emailCanonical as Any,
"emailIsFree" to emailIsFree as Any,
"emailIsDisposable" to emailIsDisposable as Any,
"emailIsCorporate" to emailIsCorporate as Any,
"emailIsCanonical" to emailIsCanonical as Any,
"phoneVerification" to phoneVerification as Any,
"mfa" to mfa as Any,
"prefs" to prefs.toMap() as Any,
Expand All @@ -174,6 +209,11 @@ data class User<T>(
email: String,
phone: String,
emailVerification: Boolean,
emailCanonical: String?,
emailIsFree: Boolean?,
emailIsDisposable: Boolean?,
emailIsCorporate: Boolean?,
emailIsCanonical: Boolean?,
phoneVerification: Boolean,
mfa: Boolean,
prefs: Preferences<Map<String, Any>>,
Expand All @@ -196,6 +236,11 @@ data class User<T>(
email,
phone,
emailVerification,
emailCanonical,
emailIsFree,
emailIsDisposable,
emailIsCorporate,
emailIsCanonical,
phoneVerification,
mfa,
prefs,
Expand Down Expand Up @@ -224,6 +269,11 @@ data class User<T>(
email = map["email"] as String,
phone = map["phone"] as String,
emailVerification = map["emailVerification"] as Boolean,
emailCanonical = map["emailCanonical"] as? String,
emailIsFree = map["emailIsFree"] as? Boolean,
emailIsDisposable = map["emailIsDisposable"] as? Boolean,
emailIsCorporate = map["emailIsCorporate"] as? Boolean,
emailIsCanonical = map["emailIsCanonical"] as? Boolean,
phoneVerification = map["phoneVerification"] as Boolean,
mfa = map["mfa"] as Boolean,
prefs = Preferences.from(map = map["prefs"] as Map<String, Any>, nestedType),
Expand Down
Loading