Joystream / orion

Atlas backend
GNU General Public License v3.0
7 stars 14 forks source link

Rethinking the Orion account creation/signup flow #320

Open zeeshanakram3 opened 5 months ago

zeeshanakram3 commented 5 months ago

This issue attempts to propose an alternate way for the creation of User/Gateway accounts

Current Implementation

Current graphql schema definition for Account entity.

"A Gateway Account"
type Account @entity @schema(name: "admin") {
  "Unique identifier (can be sequential)"
  id: ID!

  "Gateway account's e-mail address"
  email: String! @unique

  "On-chain membership associated with the gateway account"
  membership: Membership! @unique

  "Blockchain (joystream) account associated with the gateway account"
  joystreamAccount: String! @unique

  ###
  # Other field
  # ... 
}

Problems/inconsistencies in current implementation

I am not sure why this API design approach was picked (i.e. passing the membership to be associated with the account in the create account request), the alternate approach can be to associate membership later to the account using a separate endpoint by sending the memberId in request signed by account.joystreamAccount? (But I am going to suggestion a different approach)

Alternate Signup approach

Objectives of the signup flow rework

Orion schema changes

The following changes have been proposed to the Orion Graphql/DB schema

Added EmailConfirmationToken entity

A new hidden entity will be created to securely store the email confirmation tokens issued for the emails.

type EmailConfirmationToken @entity @schema(name: "admin") {
  "The token itself (32-byte string, securely random)"
  id: ID!

  "When was the token issued"
  issuedAt: DateTime!

  "When does the token expire or when has it expired"
  expiry: DateTime!

  "The email the token was issued for"
  email: String!
}

Added BlockchainAccount entity

type BlockchainAccount @entity {
  "The blockchain account id/address"
  id: ID!

  "Membership associated with the blockchain account (controllerAccount)"
  memberships: [Membership!] @derivedFrom(field: "controllerAccount")
}

Updated Account entity

Updated Account entity to have a one-to-one relationship with the BlockchainAccount entity, which then would have a One-to-Many relationship with the Membership entity.

This way we would get rid of the membership column/field from the account (no direct association), and to know about account 's membership/s we can just traverse the relation i.e. account.joystreamAccount.memberships

Another benefit of using this approach is that we don't need to perform membership association action separately, it will happen automatically (once the Account owner create an on-chain membership using keypair of account.joystreamAccount).

type Account @entity @schema(name: "admin") {
  "Unique identifier (can be sequential)"
  id: ID!

  "Gateway account's e-mail address"
  email: String! @unique

  "Blockchain (joystream) account associated with the gateway account"
  joystreamAccount: BlockchainAccount! @unique

  ###
  # Other field
  # ... 
}

Orion Auth API changes

Updated POST /request-email-confirmation-token endpoint

Although, the email confirmation endpoint already existed, it was not used. Also, if the account/email was already verified it returned explicit response stating that given email is already verified (basically revealing emails)

So updated this endpoint to send an email with a confirmation token if the Gateway account does not exist. Otherwise, send an email asking the user to log in/reset the password. but the API response should be the same to avoid email enumeration attacks.

Updated POST /account endpoint

Update create account API request to also require emailConfirmationToken that was sent to user email.

Added createAccountMembership mutation

Added createAccountMembership to create a captcha-free membership for an existing Account (if no membership for account exists yet)

Sequence diagram of new flow

YPP User Flow

  1. Youtube Video URL Entry: The creator enters the Youtube Video URL in Atlas.
  2. Channel Verification: Atlas calls the YT-synch POST /users endpoint for channel verification.
    • If verification is successful, proceed to email address input.
    • f unsuccessful, indicate the user does not meet requirements but can still create an account on Atlas as a non-YPP user.
  3. Email Address Input: The User provides an email address for the new account.
  4. Request Email Confirmation: Atlas requests an email confirmation token from Orion.
  5. User Clicks Confirmation Link: In the received email.
  6. Password Input: The User provides a password for the new account.
  7. Show Mnemonic/Seed Phrase: Atlas shows the mnemonic/seed phrase to the user.
  8. Account Creation: Atlas calls Orion's POST /account endpoint.
    • If there's an error, stop the process and show the error message.
  9. Membership Check and Creation: If no Joystream membership exists, Atlas creates one.
  10. Channel Creation: Atlas creates a Joystream channel for the creator.
  11. Channel Association: Atlas associates the Joystream channel with the Youtube channel.

Non-YPP User Flow

  1. Email Address Input: The flow starts from this step directly.
  2. Request Email Confirmation: Same as in the YPP flow.
  3. User Clicks Confirmation Link: Same as in the YPP flow.
  4. Password Input: Same as in the YPP flow.
  5. Show Mnemonic/Seed Phrase: Same as in the YPP flow.
  6. Account Creation: Same as in the YPP flow.
  7. Membership Check and Creation: Same as in the YPP flow.
  8. Channel Creation: Same as in the YPP flow. The flow ends here for non-YPP users.

Here is the sequence diagram for complete YPP/Orion signup flow

sequenceDiagram
    participant Creator
    participant Atlas
    participant YT-synch
    participant Orion
    participant Faucet
    participant RPC

    opt For YPP User
        Creator->>Atlas: [1] Enter Youtube Video URL
        Atlas->>YT-synch: [2] POST /users {youtubeVideoUrl: "string"}
        alt Verification Successful
            YT-synch-->>Atlas: [3] Response {channel details}
        else Verification Unsuccessful
            YT-synch-->>Atlas: [3] Error {does not meet requirements}
            Atlas-->>Creator: [4] Can still create account (Non-YPP)
        end
    end

    Atlas-->>Creator: [5] Ask for email address
    Atlas->>Orion: [6] requestEmailConfirmationToken {email}
    Orion-->>Atlas: [7] {success: true}
    Orion-->>Creator: [8] Email with confirmation link

    Creator->>Atlas: [9] Clicked confirmation link
    Atlas-->>Creator: [10] Ask to set password
    Atlas-->>Creator: [11] Show mnemonic/seed phrase

    Atlas->>Orion: [12] POST /account {account details with emailConfirmationToken}
    Orion-->>Atlas: [13] {success: true}

    Atlas->>Orion: [14] Check for existing membership
    alt No Existing Membership
        Creator->>Atlas: [15] Provide membership details
        Atlas->>Orion: [16] createAccountMembership {membership details}
        Orion->>Faucet: [17] Request membership creation
        Faucet-->>Orion: [18] Membership ID
        Orion-->>Atlas: [19] {membership details}
        Atlas->>RPC: [20] Create Joystream channel
        RPC-->>Atlas: [21] Channel creation confirmation
    else Existing Membership
        Atlas-->>Creator: [15] Membership exists, creating channel
        Atlas->>RPC: [16] Create Joystream channel
        RPC-->>Atlas: [17] Channel creation confirmation
    end

    opt For YPP User
        Atlas->>YT-synch: [22] POST /channels {channel association details}
        alt Channel Association Successful
            YT-synch-->>Atlas: [23] Channel association confirmation
        else Channel Association Error
            YT-synch-->>Atlas: [23] Error {reason}
        end
    end
kdembler commented 5 months ago

@zeeshanakram3 I only skimmed through, but since this is redesigned, do you think Orion could allow signup without an email, using only web3 wallet? Or would that mess up other things?

msmadeline commented 4 months ago

@zeeshanakram3 @bedeho Hey! I did the YPP sign up user flows. Please let me know If I didn't miss anything and let me know your thoughts

➡ Figma link: https://www.figma.com/file/oQqFqdAiPu16eeE2aA5AD5/YouTube-Partner-Program?type=design&node-id=6073-75786&mode=design&t=ocva97RkTpv8zpQI-4 🎥 loom video: https://www.loom.com/share/c519b36bbcb64aca8efc06b4711c0b77?sid=2d61d2f6-881e-403b-a958-ad997a6db5de

bedeho commented 4 months ago

@zeeshanakram3 I only skimmed through, but since this is redesigned, do you think Orion could allow signup without an email, using only web3 wallet? Or would that mess up other things?

We briefly discussed this, and it requires substantial effort to rework backend, and it adds more complexity. Even if it did not though, I don't think it has enough value. Its a strictly worse experience also in terms of utility post signup, as you get no notifications, which are really quite important. Anyone who insists on doing extension based signer can still just add a throwaway email, and until a substantial number of users voiced this I think its hard to justify adding a separate mode for it.

My understanding is that you are really i favour of this because you feel it has bad optics, but I don't think this really is a big issue - people are by now very used to abstracted wallet experiences, and even if it did have bad optics, the severity is not high enough in my opinion.

bedeho commented 4 months ago

I left full review in the Figma.

msmadeline commented 4 months ago

Hey @bedeho @zeeshanakram3 I have a question that I need to ask related to the sign up flows

  1. Are we creating a new Non-YPP/normal flow from scratch? So far I've done it based on the steps that @zeeshanakram3 provided but now looking at it and thinking about it - we already have a sign up flow in gleev where we already have a place where user has to provide an email address etc. So the question is should I just add the new elements to the already existing non YPP sign up flow? so the link that user has to click on etc. and make sure it's in the order that is correct now or are we doing it from scratch? Because then I will need to redesign it in all the places in the app.
msmadeline commented 4 months ago

Hey @bedeho @zeeshanakram I recorded a very quick video about my question related to non - YPP sign up flow. Let me know If I missed anything

🎥https://www.loom.com/share/f5948fe816424aa18b2db7e80d328a71?sid=4a0949e5-6c02-4a39-91df-1dec84ca302c

msmadeline commented 3 months ago

@bedeho @zeeshanakram3 Hey! I've implemented the last feedback that you provided✅ Let me know what do you think!

➡ figma file: https://www.figma.com/file/oQqFqdAiPu16eeE2aA5AD5/YouTube-Partner-Program?type=design&node-id=6073-75786&mode=design&t=I094jS7wjVSgxz47-4

🎥 loom video: https://www.loom.com/share/072d08a9191d485e89b3e5c1328b2c58?sid=37fd601e-b1aa-414c-82d8-2c200617a936

bedeho commented 3 months ago

Upload YouTube Video modal

Confusion

I don't think this works still I'm afraid.

The user will not know what we want to them to do or why. I think the title and copy is suboptimal, it just tells the user what to do, but this does not address what the point is, and a very large share of users will not pick up that the purpose of the upload is not to promote something to their users.

But even if it was optimal, I think it will unfortunately require too much tiny text in one screen, this dialog has way too much going on now

  1. tell user to upload a video, but unclear which video or if any video is ok
  2. tell user to get URL and enter it below
  3. tell user it can be unlisted, so its not that someone else needs to see it, its so we can see it, but even this latter point is not so clear
  4. tell user it has to have a very especific title
  5. tell user where to enter video and allow them to go to next page.
  6. also it will now, if you add next section (Validation), need to tell user what may be going wrong with current candidate video

This is just too much, and the user will still not understand why.

--

If you feel there is no alternative solution that can address this in some more fundamental way, my guess for at least what would be an improvement would be

Then when the user clicks continue, then some sort of indication about cause of failure is displayed if the valiation failed.

Validation

So whenver the user enters a URL, we can directly in Atlas do the check to make sure

By checking this client side, we can immediately indicate to the user that the video very likely will bea ccepted.

I guess it can be as simple as when the user clicks continue, ew do all the checks, which will be possible in 1-3seconds, and then we give some sort of indication about what conditions are or are not satisified, if not all are satisfied. If all are satisfied, then we can proceed to the nxt screen.

Verifying channel ownerhsip...

My understanding is that this should only take a few seconds, because the video does not even need to be downloaded.

User click on the confirmation link

Perhaps I'm missing something ,but I don't see a screen which comes after the user has submitted the email? There needs to be a screen which says something like "go to your email and click on link we sent you," type of thing.

msmadeline commented 3 months ago

Hey @bedeho @zeeshanakram3 I've implemented the last feedback that you gave me. Let me know wdyt!

➡Figma link: https://www.figma.com/file/oQqFqdAiPu16eeE2aA5AD5/YouTube-Partner-Program?type=design&node-id=6073-75786&mode=design&t=DkNdFHDQyhH0QXFI-4

🎥loom video: https://www.loom.com/share/5a538ce98e584870a110cfe0143802d7?sid=af835100-60fb-456a-be8c-2204ef701040

bedeho commented 3 months ago

Prove channel owernship

So thank you for trying a new iteration. I can see you have tried to explain as much as possible to the user, to make them undrestand why they are doing somtehing, but I'm worried this is too much, people will just skip and zone out.

Can we try a super simple alternative, so I can see how it works.

By default we have nothing else, there is also no "sign in" button, as I dont see a need for it?

When user clicks "continue", which we should just call "Verify video", we do client side check, and only if it fails do we display some error information, so we drop the "your video must:..". The errors will be one among:

These errors can just be displayed as red text, and we only need to show one at a time, and we don't need to show the requirements that are satisfied, again just to simplify. Notice that we don't need to actually require that the video is unlisted, this is only something the creator needs to understand is possible as an option. Notice that everything above is on one screen.

If client side verification passes, we should show a new window where we have their channel avatar, name, and title of window is something like "Ownership Verified". This tells the use very clearly that the prior step suceeded, and this may be required as I suspect people may end up failing a few times in the prior step. This window just has button "Create Account" or something, and "cancel" of course. When user clicks "create...", we just have this screen in some loading state, like with a spinner over the button or sometihng, we dont need a new window. Currentyl we have "Veryinf channel woernship", but at this point it is misleading, as the user would think that we have already done that, as the user does not understand the difference between client and server validation. If there is any error, we need to send user back to prior screen with appropriate error message, just like we already do when client side validation is being done.

User click on the confirmation link

I think we need a first success window after the user has clicked link, which says something like "email verified" like a success case, so the user understand they did the right thing after leaving the prodcut, and they are suppose dto continue. If we just send user directly to create password, they may be unsure about perhaps they have been asked to start again, or if the old stuff they did failed in some way, so we need to show them the continuiity of the process is intaact. We only need a single button with "Set password" as title"

msmadeline commented 3 months ago

Hey @bedeho @zeeshanakram3 I've implemented the second feedback ✅ Let me know wdyt

➡ Figma link: https://www.figma.com/file/oQqFqdAiPu16eeE2aA5AD5/YouTube-Partner-Program?type=design&node-id=6073-75786&mode=design&t=ltzf9jayfHLuZUOj-4

🎥 Loom video: https://www.loom.com/share/5d2dd24e0c3e44dfad6596c31fdb60d6?sid=6e02a68b-a259-4c04-b2e1-fc079117253c

bedeho commented 3 months ago

perfect