delavalom
delavalom
TTCTheo's Typesafe Cult
Created by ruhroh on 5/21/2023 in #questions
Typescript error when trying to access more user properties in my JWT token
Next-auth uses Module Augmentation to customize the types, so you don't need to change the node_modules: https://next-auth.js.org/getting-started/typescript#module-augmentation Anyways, to solve this, type the following:
import {
type DefaultSession,
type DefaultUser,
} from "next-auth";
import { type DefaultJWT } from "next-auth/jwt";

declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
name: string;
};
username: string; // Here you are telling typescript that you session will have the username property, if you want your client to have access to this property
}
interface User extends DefaultUser {
username: string; // the user will now have the property
}
}

declare module "next-auth/jwt" {
interface JWT extends DefaultJWT {
id: string;
username: string; // also my jwt will have the property, I can access this property within the JWT using the getToken() helper
}
}

export const authOptions: NextAuthOptions = {
session: {
strategy: "jwt",
},
callbacks: {
jwt({ token, user, account }) {
if (account && account.access_token) {
token.id = user.id;
token.username = user.username; // asign the value
}
return token;
},
session({ session, token }) {
session.user.id = token.id;
session.username = token.username; // pass the value to the client session

return session;
},
},
import {
type DefaultSession,
type DefaultUser,
} from "next-auth";
import { type DefaultJWT } from "next-auth/jwt";

declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
name: string;
};
username: string; // Here you are telling typescript that you session will have the username property, if you want your client to have access to this property
}
interface User extends DefaultUser {
username: string; // the user will now have the property
}
}

declare module "next-auth/jwt" {
interface JWT extends DefaultJWT {
id: string;
username: string; // also my jwt will have the property, I can access this property within the JWT using the getToken() helper
}
}

export const authOptions: NextAuthOptions = {
session: {
strategy: "jwt",
},
callbacks: {
jwt({ token, user, account }) {
if (account && account.access_token) {
token.id = user.id;
token.username = user.username; // asign the value
}
return token;
},
session({ session, token }) {
session.user.id = token.id;
session.username = token.username; // pass the value to the client session

return session;
},
},
Read all my comments in the code, also make sure to retrieve the username from the provider in my case using Github I get the username like this:
providers: [
GithubProvider({
clientId: env.NEXT_PUBLIC_CLIENT_ID,
clientSecret: env.CLIENT_SECRET,
profile(profile) {
return {
id: profile.id.toString(),
name: profile.name,
username: profile.login,
email: profile.email,
image: profile.avatar_url,
};
},
}),
],
providers: [
GithubProvider({
clientId: env.NEXT_PUBLIC_CLIENT_ID,
clientSecret: env.CLIENT_SECRET,
profile(profile) {
return {
id: profile.id.toString(),
name: profile.name,
username: profile.login,
email: profile.email,
image: profile.avatar_url,
};
},
}),
],
4 replies
TTCTheo's Typesafe Cult
Created by haardik | LearnWeb3 on 5/9/2023 in #questions
Infer nested type of trpc router return type
I believe you need to infer the output of the router. So this should help you https://trpc.io/docs/client/infer-types#inferring-input--output-types
4 replies
TTCTheo's Typesafe Cult
Created by Debaucus on 3/31/2023 in #questions
tRPC query 'train'. what's the correct method to grab data from multiple sources?
The Prisma client it's very flexible, you can query relations between tables, this allows you to avoid extra calls to the db in this procedure. In this case it will be like this:
getUniqueUser: publicProcedure
.input(z.string())
.query(async ({ ctx, input }) => {
const uniqueServer = await ctx.prisma?.user.findUnique({
where: {
name: input,
},
include: {
posts: true, // here you saying to prisma to return the posts related to this user
},
});

if (!uniqueServer) {
throw new TRPCError({
code: "NOT_FOUND",
message: `No post with id '${input}'`,
});
}

return uniqueServer;
}),
getUniqueUser: publicProcedure
.input(z.string())
.query(async ({ ctx, input }) => {
const uniqueServer = await ctx.prisma?.user.findUnique({
where: {
name: input,
},
include: {
posts: true, // here you saying to prisma to return the posts related to this user
},
});

if (!uniqueServer) {
throw new TRPCError({
code: "NOT_FOUND",
message: `No post with id '${input}'`,
});
}

return uniqueServer;
}),
To know more about you can refer to the prisma [docs] (https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries).
13 replies
TTCTheo's Typesafe Cult
Created by Debaucus on 3/31/2023 in #questions
tRPC query 'train'. what's the correct method to grab data from multiple sources?
I don't think you need to query from multiple sources when your page load. If you have your router file system like this:
├── src/
│ └── pages
│ └── profile
│ └──[username]
├── src/
│ └── pages
│ └── profile
│ └──[username]
You could do this:
// Inside your component
const { query, isReady } = useRouter()
// Fetch the router data
const { data: posts, isLoading } = trpc.user.getUserPosts.useQuery(
{ username: query.username,
// use the username route to query your db
{
enabled: router.isReady,
// wait until the useRouter() hook finished fetching the router data
}
)
// Inside your component
const { query, isReady } = useRouter()
// Fetch the router data
const { data: posts, isLoading } = trpc.user.getUserPosts.useQuery(
{ username: query.username,
// use the username route to query your db
{
enabled: router.isReady,
// wait until the useRouter() hook finished fetching the router data
}
)
I'm assuming this is the architecture of your tRPC server and that you're using ReactQuery
13 replies
TTCTheo's Typesafe Cult
Created by nozadev on 3/18/2023 in #questions
Is it okay to have CredentialsProvider as JWT and save Google/Discord users in database session?
You're right, I mistake Credentials provider with Email provider. I haven't encounter to store OAuth sessions in db with Credentials provider as this required you to use JWT strategy for sessions. I'd have to try it
7 replies
TTCTheo's Typesafe Cult
Created by nozadev on 3/18/2023 in #questions
Is it okay to have CredentialsProvider as JWT and save Google/Discord users in database session?
You can have both google and traditional auth providers, store users, accounts, and verification tokens (required for email/password) in database, and use JWTs to store session details. This way you have less data stored in the database.
7 replies