Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profile picture generation in the frontend #1202

Closed
DerMolly opened this issue Apr 26, 2021 · 5 comments · Fixed by #5012
Closed

Profile picture generation in the frontend #1202

DerMolly opened this issue Apr 26, 2021 · 5 comments · Fixed by #5012
Assignees
Labels
type: feature Adds or requests new functionality
Milestone

Comments

@DerMolly
Copy link
Member

DerMolly commented Apr 26, 2021

Which part of the project should be enhanced?
user service, photo generation

Is your enhancement request related to a problem? Please describe.
We need to create photos for user that don't have any.

In 1.x we did it this way (thanks to @ErikMichelson for the disection):

HedgeDoc 1.x uses three places where (sometimes different) avatar images are used:

  • The online status indicator
  • The information line above a note (note creator, last editor)
  • The user dropdown on the intro/history page

There is no possibility to upload an own avatar to HedgeDoc 1.x, however the image to use is determined like this:

  • When a user account is created, the profile data of the external provider (usually the OAuth2 /userinfo endpoint) is stringified into the profile column of the database. Local (email) users have an empty profile.

  • The /me route as well as the realtime code responsible for extracting the user that last changed a note both call the getProfile method of an User object, that tries to parse the database profile column and then determines the profile picture from that as following:

    1. The profile.provider is set to an auth provider that serves the profile pictures of the user. In that case this will be just taken. (Applies to Facebook, Twitter, GitHub, GitLab, Mattermost, Google)
    2. The profile.provider is set to an auth provider that does not serve the users' profile picture OR the user has no profile picture on one of the previous providers OR profile.provider is not set. In that case generateAvatarURL method is called, which does the following differentiation:
      1. The user has an email address set (profile.email) AND config.allowGravatar is enabled. In that case the email address is md5'ed and given to Libravatar for retrieving the picture.
      2. The user has no email address AND config.allowGravatar is enabled. In that case the username is prepended before "@example.com" and given to Libravatar.
      3. Otherwise the API route /user/<username>/avatar.svg is returned. <username> in this case is either the localpart of the email address or the username if no email is set or the md5 hash of the email address (WHY?).
  • The API route mentioned above does the following:

    1. Generate a random "dark" color with the username as seed for the generator.
    2. Take the first letter of the username and uppercase it.
    3. Create a SVG file that contains the color as background color and the letter as a text element on it.
  • The status list icon inside the editor only checks if a user from the list of users returned by the websocket action online users contains a photo property (which it only does if the login provider has provided one, see updateUserData method). If so, it takes this, otherwise it uses a randomly generated color as background-image for the profile picture placeholder container.


Describe the solution you'd like
Generating a data-URI with a svg in it, that shall be used for logged-in users without an image.

Anonymous users could, just give themselves (or rather the frontend give sthem) a random name and a random color. This way the could be clearly distinguished from logged-in users.

It seems reasonable to include a deterministic way of generating images, so a user always get's the same image. As such it probably should be based on the userName, because that won't change for a user…

Also we probably won't want to build our own image generation lib, because there are ton out there.

@mrdrogdrog suggested using either

https://avatars.dicebear.com/ with human, avataaars or bottts (see Licenses)
or
https://jdenticon.com/, possibly limiting ourselves to the hedgedoc color scheme (see here)

Describe alternatives you've considered
Eh. I don't know.

Additional context

Relevant code segments (1.x Code)

@DerMolly DerMolly added the type: feature Adds or requests new functionality label Apr 26, 2021
@SISheogorath
Copy link
Contributor

SISheogorath commented Apr 27, 2021

First of all, I would recommend that we look into full libravatar support (including federated avatars) as well as providing a avatar generator in HedgeDoc itself. Here we can benefit from the work I did for Libravatar this year: https://git.linux-kernel.at/oliver/ivatar/-/issues/72

Edit: Sorry for the mess here, my browser decided that buttons and text fields shouldn't have the same "action area" as their display representation.

@davidmehren
Copy link
Member

If this issue is just about anonymous users, how does libravatar support help here?
As far as I understand, it requires an email address.

Both dicebear and jdenticon look suitable to deterministically generate a profile picture from the random ID we have for each anonymous user, although dicebear seems to be a bit more actively maintained.

@SISheogorath
Copy link
Contributor

If this issue is just about anonymous users, how does libravatar support help here?

I misunderstood the issue to be about replacing the existing endpoint which covers more than just anonymous users. However my pointer was towards similar efforts, avatar generation, on libravatar's side, so we don't have to do the whole library research ourselves.

And while libravatar seems to require an email address, since the backend isn't aware what was passed through the md5 or sha256 function, it can work with any string (besides that libravatar itself usually requires either an e-mail address or an OpenID identifier when you want to benefit from accounts or federated discovery, but that's not important now).

@mrdrogdrog
Copy link
Member

mrdrogdrog commented May 10, 2021

@ErikMichelson and myself had an idea:
Why does the backend need to know anything about avatars? The only place where we need the avatar images is in the frontend. Since you can't upload your own image, the frontend can fetch the correct images from the auth providers or generate a mock image.
From a data privacy point of view this is not more dangerous than the image feature in the markdown renderer.

@davidmehren davidmehren added this to the Release 2.0 milestone Oct 25, 2021
@davidmehren
Copy link
Member

davidmehren commented Oct 7, 2023

Okay, so we need to:

  • Let the backend fetch a profile picture URL via libravatar (Implement libravatar support #5010)
  • Let the frontend generate a unique picture when the backend does not provide one (this issue)

@davidmehren davidmehren changed the title [UserService] user photo generation Profile picture generation in the frontend Oct 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature Adds or requests new functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants