Skip to content

Conversation

@nfebe
Copy link
Contributor

@nfebe nfebe commented Apr 22, 2024

The contact entry should carry cloud information, this can help to fix various issues including:

  • Displaying correct avatar links for federated users

This can also lead to UI improvements in the frontend where, it's federated contacts are shown with a marker or indicator on the UI.

Summary

TODO

  • ...

Checklist

@nfebe nfebe force-pushed the 44319-fix-fed-share-user-avatars branch 2 times, most recently from 70f529c to fe83f91 Compare April 22, 2024 09:08
$this->cloud = $cloudId;
}

public function getCloud(): CloudId {

Check failure

Code scanning / Psalm

InvalidNullableReturnType

The declared return type 'OC\Federation\CloudId' for OC\Contacts\ContactsMenu\Entry::getCloud is not nullable, but 'OC\Federation\CloudId|null' contains null
}

public function getCloud(): CloudId {
return $this->cloud;

Check failure

Code scanning / Psalm

NullableReturnStatement

The declared return type 'OC\Federation\CloudId' for OC\Contacts\ContactsMenu\Entry::getCloud is not nullable, but the function returns 'OC\Federation\CloudId|null'
@nfebe nfebe force-pushed the 44319-fix-fed-share-user-avatars branch from fe83f91 to 8640581 Compare April 22, 2024 15:34
Copy link
Contributor Author

@nfebe nfebe left a comment

Choose a reason for hiding this comment

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

To solve this issue we could simple use the isUser property of the contact along side isNouser boolean of NcAvatar to show the text generated icons.

However, here:

  • I instead try to link to the actual avatars on the remote server, since the links public
  • I am adding the cloud data to be passed to the frontend

Problems:

  • This code is able to load the avatars from a federated server but would like to "Content Security Policy" errors if the remote server is unsecured.

There are other places in the code base such as here where the current approach is used but we could swap if this attempt to directly load the avatars from the federated server is successful/useful.

@nickvergessen since you are familiar with section of the code, does this approach make sense?

@nfebe nfebe force-pushed the 44319-fix-fed-share-user-avatars branch from 8640581 to 2b1c1ab Compare April 22, 2024 15:43
The contact entry should carry cloud information, this can help to fix various issues including:

- Displaying correct avatar links for federated users

This can also lead to UI improvements in the frontend where, it's federated contacts are shown with
a marker or indicator on the UI.

Signed-off-by: fenn-cs <[email protected]>
@nfebe nfebe force-pushed the 44319-fix-fed-share-user-avatars branch from 2b1c1ab to 990d244 Compare April 22, 2024 15:46
} elseif (!empty($contact['FN'])) {
$avatar = $this->urlGenerator->linkToRouteAbsolute('core.GuestAvatar.getAvatar', ['guestName' => str_replace('/', ' ', $contact['FN']), 'size' => 64]);
} elseif ($username != '') {
$avatar = $this->urlGenerator->linkToRemoteRouteAbsolute($remoteServer, 'core.avatar.getAvatar', ['userId' => str_replace('/', ' ', $username), 'size' => 64]);

Check failure

Code scanning / Psalm

UndefinedInterfaceMethod

Method OCP\IURLGenerator::linkToRemoteRouteAbsolute does not exist
$avatar = $this->urlGenerator->linkToRemoteRouteAbsolute($remoteServer, 'core.avatar.getAvatar', ['userId' => str_replace('/', ' ', $username), 'size' => 64]);
} else {
$avatar = $this->urlGenerator->linkToRouteAbsolute('core.GuestAvatar.getAvatar', ['guestName' => str_replace('/', ' ', $uid), 'size' => 64]);
$avatar = $this->urlGenerator->linkToRemoteRouteAbsolute($remoteServer, 'core.avatar.getAvatar', ['userId' => str_replace('/', ' ', $uid), 'size' => 64]);

Check failure

Code scanning / Psalm

UndefinedInterfaceMethod

Method OCP\IURLGenerator::linkToRemoteRouteAbsolute does not exist
$this->id = $id;
}

public function getId(): string {

Check failure

Code scanning / Psalm

InvalidNullableReturnType

The declared return type 'string' for OC\Contacts\ContactsMenu\Entry::getId is not nullable, but 'null|string' contains null
}

public function getId(): string {
return $this->id;

Check failure

Code scanning / Psalm

NullableReturnStatement

The declared return type 'string' for OC\Contacts\ContactsMenu\Entry::getId is not nullable, but the function returns 'null|string'
}


public function linkToRemoteRouteAbsolute(string $remote, $routeName, array $arguments = []): string {

Check failure

Code scanning / Psalm

InvalidNullableReturnType

The declared return type 'string' for OC\URLGenerator::linkToRemoteRouteAbsolute is not nullable, but 'null|string' contains null


public function linkToRemoteRouteAbsolute(string $remote, $routeName, array $arguments = []): string {
return $this->formatAsUrl($remote, $this->linkToRoute($routeName, $arguments));

Check failure

Code scanning / Psalm

NullableReturnStatement

The declared return type 'string' for OC\URLGenerator::linkToRemoteRouteAbsolute is not nullable, but the function returns 'null|string'
$remoteServer = '';

if (isset($contact['CLOUD']) && is_array($contact['CLOUD']) && isset($contact['CLOUD'][0])) {
preg_match('/^(.*?)@(https?:\/\/.*?)$/', $contact['CLOUD'][0], $matches);
Copy link
Member

Choose a reason for hiding this comment

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

Please use the ICloudManager::resolve() method instead?


/**
* @return array{id: int|string|null, fullName: string, avatar: string|null, topAction: mixed, actions: array, lastMessage: '', emailAddresses: string[], profileTitle: string|null, profileUrl: string|null, status: string|null, statusMessage: null|string, statusMessageTimestamp: null|int, statusIcon: null|string, isUser: bool, uid: mixed}
* @return array{id: int|string|null, fullName: string, avatar: string|null, topAction: mixed, actions: array, lastMessage: '', emailAddresses: string[], profileTitle: string|null, profileUrl: string|null, status: string|null, statusMessage: null|string, statusMessageTimestamp: null|int, statusIcon: null|string, isUser: bool, uid: mixed, cloud: mixed}
Copy link
Member

Choose a reason for hiding this comment

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

cloud should be called cloudId to be more clear and the type should be the array you define in the other file

/**
* @return array{id: string, user: string, remote: string, displayName: string|null}
*/
public function jsonSerialize(): array {
Copy link
Member

Choose a reason for hiding this comment

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

Should implement the interface JsonSerializable?

Copy link
Member

Choose a reason for hiding this comment

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

That being said, should be on the public interface?

} elseif (!empty($contact['FN'])) {
$avatar = $this->urlGenerator->linkToRouteAbsolute('core.GuestAvatar.getAvatar', ['guestName' => str_replace('/', ' ', $contact['FN']), 'size' => 64]);
} elseif ($username != '') {
$avatar = $this->urlGenerator->linkToRemoteRouteAbsolute($remoteServer, 'core.avatar.getAvatar', ['userId' => str_replace('/', ' ', $username), 'size' => 64]);
Copy link
Member

Choose a reason for hiding this comment

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

This assumes every cloud ID is a nextcloud? 🫣

}


public function linkToRemoteRouteAbsolute(string $remote, $routeName, array $arguments = []): string {
Copy link
Member

Choose a reason for hiding this comment

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

This should not be here or on the public interface

@nickvergessen
Copy link
Member

does this approach make sense

From my POV it's not okay...

@nfebe
Copy link
Contributor Author

nfebe commented Apr 22, 2024

Based on conversation with @nickvergessen, this needs more effort especially as the content security policy can't changed to allow all trusted servers.

So this would remain in draft in favor of : #44972

Eventually, I could copy the proxy strategy from https://github.com/nextcloud/spreed/blob/main/lib/Controller/AvatarController.php#L244 where the server downloads the image and sends in on the instance URL.

@nfebe nfebe added descoped and removed 2. developing Work in progress labels Apr 22, 2024
@solracsf solracsf added this to the Nextcloud 30 milestone Jun 18, 2024
@skjnldsv skjnldsv added the 2. developing Work in progress label Jul 27, 2024
@skjnldsv skjnldsv modified the milestones: Nextcloud 30, Nextcloud 31 Aug 14, 2024
@susnux susnux added stale Ticket or PR with no recent activity and removed descoped labels Nov 4, 2024
@blizzz blizzz modified the milestones: Nextcloud 31, Nextcloud 32 Feb 26, 2025
@skjnldsv skjnldsv closed this Jul 11, 2025
@skjnldsv
Copy link
Member

Closing as stale and EOL branch.
If still required, please resume your work on it by rebasing and requesting for reviews again 🙏

@skjnldsv skjnldsv modified the milestones: Nextcloud 32, Nextcloud 33 Sep 28, 2025
@susnux susnux deleted the 44319-fix-fed-share-user-avatars branch November 1, 2025 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2. developing Work in progress feature: contacts menu feature: search stale Ticket or PR with no recent activity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants