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

write auth for farcaster and lens #1237

Merged
merged 9 commits into from
Nov 2, 2023
Merged

write auth for farcaster and lens #1237

merged 9 commits into from
Nov 2, 2023

Conversation

benny-conn
Copy link
Collaborator

@benny-conn benny-conn commented Oct 24, 2023

Changes:

  • Changed farcaster and lens auth to optionally include fields for signing and authenticating with OAuth
  • Added polling task queue for polling farcaster signer approval

Farcaster is by far the more complex flow, here is how this PR works to accomplish authenticated farcaster connections:

  1. When connecting social auth, user can optionally request withSigner in the graphQL request that will have Neynar generate a "signer". A signer is useless until approved by the user later in this process but we don't want to expose the signer_uuid which is sort of like the "access token" in farcaster.
  2. We use our official gallery farcaster private key to sign the public key associated with this signer and send it to neynar, basically saying "gallery wants this guy to approve us to act on his behalf".
  3. We get back an "approval URL" that will be sent to the user and can be used to approve gallery in an on-chain transaction. This will be returned in the FarcasterSocialAccount type as well as the status of their approval. The frontend has to give this URL to the user.
  4. Simultaneously, we kick off a retryable task to the autosocial service that will continuously check if the user approved the token. Once they do, it will update their status to approved.

The last step is to match the "deadline" of the signature to whatever the cloud task total retry time is so that we don't run into a case where a user successfully approves of a token and we didn't poll for it. If this does happen, this isn't the end of the world, but might lead to us telling the user "you haven't approved of gallery to act on your behalf" when they in fact have. We could also remove the polling altogether but then the frontend would have no way of showing the user that they successfully connected.

Copy link
Contributor

@radazen radazen left a comment

Choose a reason for hiding this comment

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

Good job figuring this stuff out, @benny-conn! Looks great to me. 🥇

return
}

logger.For(c).Infof("checking farcaster approval for %s", in.SignerUUID)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is SignerUUID sensitive enough that we shouldn't log it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes!

# farcaster only supports ETH addresses currently so no need to specify a chain
}

input LensAuth {
address: Address!
signature: String @scrub
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be helpful to document the withSigner and signature parameters so callers know what happens if they provide them. You can use """ to add documentation comments to the schema """like this""".

appFid := new(big.Int)
appFid.SetString(appFidStr, 10)

deadline := big.NewInt(time.Now().Unix() + 86400)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think 86400 could benefit from being a constant. Personally, I like defining time constants in a way that makes the duration and units obvious, like:

const expirationSeconds = 60 * 60 * 24 // 24 hours

return nil, err
}

logger.For(ctx).Warnf("account %s", account.Address.Hex())
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still need this?

defer tracing.FinishSpan(span)
queue := env.GetString("AUTOSOCIAL_POLL_QUEUE")
url := fmt.Sprintf("%s/checkFarcasterApproval?signer_uuid=%s&user_id=%s", env.GetString("AUTOSOCIAL_URL"), message.SignerUUID, message.UserID)
return submitTask(ctx, client, queue, url, withTrace(span))
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think the retry on this will look like? Seems like we'll want to try a bunch early on so we can be quick to update their account if they do the on-chain thing, but we probably want to back off significantly if they don't do the transaction right away.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sounds good to me. I imagine this will all be in the span of about 10 minutes as well.

@benny-conn benny-conn merged commit 53beb04 into main Nov 2, 2023
5 checks passed
@benny-conn benny-conn deleted the benny/social-write-auth branch November 2, 2023 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants