timmm | DexFi Gia Dev
timmm | DexFi Gia Dev•2mo ago

Using Twitter with Convex Auth

I'm wondering how caching works for sub queries. I have a queryWithSession query - if I have a general query inside this one will that be cached? Or is it only the parent queries that get cached?
51 Replies
ballingt
ballingt•2mo ago
what do you mean by query here
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
For example:
const getThing = internalQuery({
args: {},
handler: async (ctx) => {
return await ctx.db.query("thing").collect()
}
})

const getThingWithSession = queryWithSession({
args: {},
handler: async (ctx) => {
return await ctx.runQuery(internal.thing.getThing, {})
}
})
const getThing = internalQuery({
args: {},
handler: async (ctx) => {
return await ctx.db.query("thing").collect()
}
})

const getThingWithSession = queryWithSession({
args: {},
handler: async (ctx) => {
return await ctx.runQuery(internal.thing.getThing, {})
}
})
I'm using the queryWithSession to for authorization but then that makes every query unique to the user I haven't used the default auth libraries either - this is a custom implementation. I'm not sure if that matters I don't think there's another way to track the session on the server e.g. with cookies so i'm not passing different args for every user? Wondering if I've missed something
ballingt
ballingt•2mo ago
These await ctx.runQuery() calls from within another query function aren't cached today, the query function result cache is only used for the outermost query call. indeed if you pass different args or access auth in a function, these get different cache keys Typically auth is done via JWT OIDC tokens, but those get included in the cache key of a query function result if you access them in a query
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
I don't actually need them in the query key - it's purely for authentication I'll need to revisit it then Thanks @Tom
ballingt
ballingt•2mo ago
This is a known issue, we're talking about the right abstraction here; maybe it's ctx.runQuery() like you were trying (although today there's no point in doing that) today you probably never want to use ctx.runQuery() unless you're calling functions in another component possibly it's something more automatic
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Yea I imagine it's a hard problem to solve
ballingt
ballingt•2mo ago
ctx.runQuery() does run the query in another V8 isolate, it's a totally separate runtime, so its' a reasonable boundary for caching If you're in an action, your ctx.runQuery() will be a "top-level query call," so it will be cached
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
What's your recommendation on how I should roll auth? I need to auth with twitter
ballingt
ballingt•2mo ago
but then you're not reactive anymore Does Twitter give you OIDC tokens?
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Oh you're using V8 that's super interesting
ballingt
ballingt•2mo ago
The only authentication implemented over the Convex WebSocket protocol is OIDC tokens, JWTs that include an aud and an iss
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
No I don't think you can
ballingt
ballingt•2mo ago
What kind of tokens do you get from them, tokens you can refresh somehow? tokens with fields like iss?
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
It supports OAuth 2.0 My understanding is OIDC and OAuth 2.0 are two separate but related auth protocols I'm no expert on this though
ballingt
ballingt•2mo ago
yeah reading twitter auth docs now I'm not seeingif they even give you JWTs the only auth Convex deals with natively is OIDC tokens, JWTs with a few required fields. If you don't have this, then yeah you'd need to send these in as arguments in each request, verify them each time, or build some sort of session that remembers that you verified them However there's a library called Convex Auth that can be your OIDC provider for you, and works with Auth.js providers. Auth.js has a Twitter provider https://authjs.dev/getting-started/providers/twitter, so that might work? but it's not one of the ones we test with the Convex Auth library
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Yea I saw convex auth. This https://labs.convex.dev/auth ?
Convex Auth - Convex Auth
Authentication library for your Convex backend
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
OK that sounds like a good idea. Is there an example somewhere of adding an Auth.js provider?
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Oh awesome. Thanks Tom
ballingt
ballingt•2mo ago
@timmm | DexFi Gia Dev I just tried and I couldn't get this to work with a free Twitter account app. I was guessing at which values to stick in which environment variables because that wasn't clear to me from https://authjs.dev/getting-started/providers/twitter
Auth.js | Twitter
Authentication for the Web
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
I'm giving it a go. Will let you know how I go
ballingt
ballingt•2mo ago
maybe still worth trying, could be that my free developer account can't do this or something
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
I'm guessing the callback url is to the convex server http api?
ballingt
ballingt•2mo ago
Yeah, this gets exposed when you follow the steps in https://labs.convex.dev/auth
ballingt
ballingt•2mo ago
this step
No description
ballingt
ballingt•2mo ago
something like https://fast-horse-123.convex.site/api/auth/callback/twitter
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Ah of course
ballingt
ballingt•2mo ago
oh I just found this part
No description
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
ok this is a bit odd - the signIn function has thrown off all my types Type instantiation is excessively deep and possibly infinite.ts(2589) Oh I know why.. nvm
ballingt
ballingt•2mo ago
what version of TypeScript are you using? is that all you added? that's not a known issue, although we've had things like that before
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
it's because I had a folder called auth already
ballingt
ballingt•2mo ago
ohhh calling it auth might be hardcoded in some spots so unfortunately you may be stuck with needing to rename your folder hm that's a bummer though, not sure exactly how that works
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Nah it's fine. It's for the auth I'll pull out
ballingt
ballingt•2mo ago
promising...
No description
ballingt
ballingt•2mo ago
ok got an error about email because email is required in Convex Auth but not provided by Twitter by default
No description
ballingt
ballingt•2mo ago
now I need to write some very simple TOS and privacy policy
No description
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Oh yep I got the same error Can I change email to optional in the schema? I'm guessing that's the way you link multiple accounts or how next auth does it
ballingt
ballingt•2mo ago
hm I wonder how much you'd need to change for that yeah there's account linking (which you can customize https://labs.convex.dev/auth/advanced) email might be too baked in I think this is possible but it's going to be some work, now is probably a good time to say consider using Clerk, they might handle this better but yeah you can customize the user table schema
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
I'm going to keep poking around... using email might not be an issue
ballingt
ballingt•2mo ago
ok it works! I made this change to the test app https://github.com/get-convex/convex-auth/tree/main/test
GitHub
convex-auth/test at main · get-convex/convex-auth
Library for built-in auth. Contribute to get-convex/convex-auth development by creating an account on GitHub.
No description
ballingt
ballingt•2mo ago
email was already optional, it just wasn't allowed to be null
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
ohhhhh
ballingt
ballingt•2mo ago
GitHub
convex-auth/test/convex/schema.ts at main · get-convex/convex-auth
Library for built-in auth. Contribute to get-convex/convex-auth development by creating an account on GitHub.
ballingt
ballingt•2mo ago
this example is totally overwriting the users table it looks like
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Hey it's working! You move so quick - thanks heaps Tom This is great. Very much appreciated!
ballingt
ballingt•2mo ago
Check out that test app for examples, you'll be on your own for creating login button etc.
ballingt
ballingt•2mo ago
I just reused the apple button, shhhhh don't tell apple
No description
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Thanks again Tom 🙂 For those coming back here later the full solution was: 1. setup convex auth as per instructions https://labs.convex.dev/auth/setup/manual 2. add the twitter provider to convex/auth.ts
import { convexAuth } from "@convex-dev/auth/server";
import Twitter from "@auth/core/providers/twitter";
import invariant from "tiny-invariant";

const xClientId = process.env.X_CLIENT_ID;
const xClientSecret = process.env.X_CLIENT_SECRET;

invariant(xClientId, "X_CLIENT_ID is not set");
invariant(xClientSecret, "X_CLIENT_SECRET is not set");

export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
providers: [
Twitter({
clientId: xClientId,
clientSecret: xClientSecret,
}),
],
});
import { convexAuth } from "@convex-dev/auth/server";
import Twitter from "@auth/core/providers/twitter";
import invariant from "tiny-invariant";

const xClientId = process.env.X_CLIENT_ID;
const xClientSecret = process.env.X_CLIENT_SECRET;

invariant(xClientId, "X_CLIENT_ID is not set");
invariant(xClientSecret, "X_CLIENT_SECRET is not set");

export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
providers: [
Twitter({
clientId: xClientId,
clientSecret: xClientSecret,
}),
],
});
3. add a custom schema for users - note that the email needs to be optionally null email: v.optional(v.union(v.string(), v.null()))
users: defineTable({
name: v.optional(v.string()),
image: v.optional(v.string()),
email: v.optional(v.union(v.string(), v.null())),
emailVerificationTime: v.optional(v.number()),
phone: v.optional(v.string()),
phoneVerificationTime: v.optional(v.number()),
isAnonymous: v.optional(v.boolean()),
}).index("email", ["email"]),
users: defineTable({
name: v.optional(v.string()),
image: v.optional(v.string()),
email: v.optional(v.union(v.string(), v.null())),
emailVerificationTime: v.optional(v.number()),
phone: v.optional(v.string()),
phoneVerificationTime: v.optional(v.number()),
isAnonymous: v.optional(v.boolean()),
}).index("email", ["email"]),
4. add the callback URL on twitter to your convex HTTP endpoint. I'm using local dev atm http://127.0.0.1:3211/api/auth/callback/twitter
Manual Setup - Convex Auth
Authentication library for your Convex backend
ballingt
ballingt•2mo ago
Nice, I set it up with environment variable instead but otherwise did the same thing
No description
No description
timmm | DexFi Gia Dev
timmm | DexFi Gia DevOP•2mo ago
Oh I will change to this. Didn't realise you could do that

Did you find this page helpful?