moroshko
moroshko
Explore posts from servers
DTDrizzle Team
Created by moroshko on 6/8/2024 in #help
How to type an optional included relation?
I'd like to implement a function that given an email returns a user. The function also gets an optional includeContacts boolean. When true, all user contacts should be returned as well. Here is what I currently have:
async function getUserByEmail(email: string, options?: { includeContacts: true }) {
const includeContacts = options?.includeContacts ?? false;
const user = await db.query.usersTable.findFirst({
where: eq(usersTable.email, email),
with: includeContacts ? { contacts: true } : undefined,
});

return user ?? null;
}
async function getUserByEmail(email: string, options?: { includeContacts: true }) {
const includeContacts = options?.includeContacts ?? false;
const user = await db.query.usersTable.findFirst({
where: eq(usersTable.email, email),
with: includeContacts ? { contacts: true } : undefined,
});

return user ?? null;
}
The problem is that user contacts are not included in the returned type. Ideally, contacts will be a non-optional field in the returned type when includeContacts is true. Is this possible to achieve? Here is my schema:
export const usersTable = pgTable("users", {
email: text("email").notNull().unique().primaryKey(),
getHeadsUp: boolean("get_heads_up").notNull(),
createdAt: timestamp("created_at").notNull().defaultNow(),
});

export const contactsTable = pgTable("contacts", {
id: text("id")
.primaryKey()
.$defaultFn(() => `ct_${crypto.randomUUID()}`),
userEmail: text("user_email").notNull(),
name: text("name").notNull(),
email: text("email").notNull(),
createdAt: timestamp("created_at").notNull().defaultNow(),
});

export const usersRelations = relations(usersTable, ({ many }) => ({
contacts: many(contactsTable),
}));

export const contactsRelations = relations(contactsTable, ({ one }) => ({
user: one(usersTable, {
fields: [contactsTable.userEmail],
references: [usersTable.email],
}),
}));
export const usersTable = pgTable("users", {
email: text("email").notNull().unique().primaryKey(),
getHeadsUp: boolean("get_heads_up").notNull(),
createdAt: timestamp("created_at").notNull().defaultNow(),
});

export const contactsTable = pgTable("contacts", {
id: text("id")
.primaryKey()
.$defaultFn(() => `ct_${crypto.randomUUID()}`),
userEmail: text("user_email").notNull(),
name: text("name").notNull(),
email: text("email").notNull(),
createdAt: timestamp("created_at").notNull().defaultNow(),
});

export const usersRelations = relations(usersTable, ({ many }) => ({
contacts: many(contactsTable),
}));

export const contactsRelations = relations(contactsTable, ({ one }) => ({
user: one(usersTable, {
fields: [contactsTable.userEmail],
references: [usersTable.email],
}),
}));
2 replies
KKinde
Created by moroshko on 4/28/2024 in #💻┃support
Custom properties added to the wrong token
No description
19 replies
KKinde
Created by moroshko on 4/28/2024 in #💻┃support
Extending KindeIdToken type to include the `organizations` claim
No description
6 replies
KKinde
Created by moroshko on 4/28/2024 in #💻┃support
useKindeAuth isLoading doesn't change to false
Trying to get the org in a client component, but isLoading does not change to false. What am I missing?
"use client";

import { useKindeAuth } from "@kinde-oss/kinde-auth-nextjs";

export const MyComponent = () => {
const { isLoading, getOrganization } = useKindeAuth();

// Prints: {isLoading: true, org: null}
console.log({
isLoading,
org: getOrganization(),
});

...
};
"use client";

import { useKindeAuth } from "@kinde-oss/kinde-auth-nextjs";

export const MyComponent = () => {
const { isLoading, getOrganization } = useKindeAuth();

// Prints: {isLoading: true, org: null}
console.log({
isLoading,
org: getOrganization(),
});

...
};
4 replies
KKinde
Created by moroshko on 4/28/2024 in #💻┃support
Getting organization handle in id token claims
When user visits myapp.com/org-handle, I'd like to check whether the user has access to the org-handle organization, and if so, show them the page. I found how to add organizations to the id token claims, but this array contains the org id and name only. I'd like the org handle to be there. Is this possible? If not, what's the recommended way to check whether the user has access to a specific org given an org handle? I also tried to fetch the list of all organizations using the Management API, but the handle is not returned there either.
8 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
Permission doesn't work
No description
2 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
How to sign the user out when /logout is visited?
In my Next.js App Router application, I'd like to automatically sign the user out when the user visits /logout. This could be helpful if the user is stuck in some weird UI state due to a bug, or the "Sign out" button is not rendered for some reason. Having a simple /logout page to reset the auth could be a time saver at times. How could I achieve this?
2 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
isAuthenticated === false vs user === null
Is there any difference (maybe performance?) between:
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";

const { isAuthenticated } = getKindeServerSession();
const isAuthed = await isAuthenticated();

if (!isAuthed) {
...
}
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";

const { isAuthenticated } = getKindeServerSession();
const isAuthed = await isAuthenticated();

if (!isAuthed) {
...
}
and
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";

const { getUser } = getKindeServerSession();
const user = await getUser();

if (!user) {
...
}
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";

const { getUser } = getKindeServerSession();
const user = await getUser();

if (!user) {
...
}
?
2 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
Multi-factor auth using SMS - Where is the user's phone number stored?
I enabled "Multi-factor authentication". The first time I logged in using Google, I was asked to enter my phone number to receive the verification code. I then logged out and logged in again. This time, the verification code was automatically sent to my previously entered phone number, which was very nice. However, I thought that the phone number would be stored in the Phone field on the user page, but the Phone field is blank. Where does Kinde store my phone number, and what happens if I enter a different phone number in the Phone field?
3 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
Protecting routes in Next.js App Router middleware
Docs at https://kinde.com/docs/developer-tools/nextjs-sdk/#protect-routes-using-middleware mention:
As of right now the middleware in the app router does not work when trying to redirect to api/auth/login. This is because of Next.js caching which causes issues during authentication.
Should I read this as "currently, protecting routes in the middleware doesn't work, and the code examples mentioned in this docs section won't work either"? When the user is signed out, and I navigate to http://localhost:3000, I can see that the middleware is hit with the api/auth/login pathname.
// middleware.ts

import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextRequest } from "next/server";

export default function middleware(req: NextRequest) {
console.log("middleware =>", req.nextUrl.pathname);

return withAuth(req);
}
// middleware.ts

import { withAuth } from "@kinde-oss/kinde-auth-nextjs/middleware";
import { NextRequest } from "next/server";

export default function middleware(req: NextRequest) {
console.log("middleware =>", req.nextUrl.pathname);

return withAuth(req);
}
So, I'm trying to understand what exactly is not working in the middleware. On another note, withAuth() doesn't seem to be properly typed. Any plans to have proper types so that we could see for example what type publicPaths is in the middleware options? I could probably guess that it's an array of strings, but no idea for example if regex is supported. Having some examples in the docs would also help 🙂
10 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
User's first and last names are overridden when user logs in using Google
After user signs up using Google, their first and last names in KindeUser are pre-populated from the Google account. I then go to the Kinde UI and update user's first and last names (these fields are not disabled after all, suggesting they can be modified). If the user now signs out and logs in again, my custom set first and last names are overridden by the Google account's ones. Is this expected? If so, why the first and last names fields in the Kinde UI aren't disabled?
5 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
`await getUser()` doesn't return the first and last name
In my Next.js App Router application, in a page component, I get the user:
const { getUser } = getKindeServerSession();

const user = await getUser();

console.log(user);
const { getUser } = getKindeServerSession();

const user = await getUser();

console.log(user);
However, the first and last names are undefined:
{
family_name: undefined,
given_name: undefined,
picture: null,
email: 'my.email@gmail.com',
id: 'kp_e302a65c21bb45a7aaa378ccb9812345'
}
{
family_name: undefined,
given_name: undefined,
picture: null,
email: 'my.email@gmail.com',
id: 'kp_e302a65c21bb45a7aaa378ccb9812345'
}
I double checked on the Kinde User page that the user id and the email are the same and that the first and last names are set there. What am I missing?
5 replies
KKinde
Created by moroshko on 4/27/2024 in #💻┃support
Does Kinde provide Login/SignUp components for custom Login/SignUp pages?
No description
14 replies
DTDrizzle Team
Created by moroshko on 8/7/2023 in #help
How to separate Dev data from Prod data with one Postgres instance?
I'd love to use Drizzle with Vercel's Postgres Storage (Neon). On the Hobby plan, Vercel offers only one Postgres instance. I realize it's not a Drizzle specific question, but would love to know what's the easiest/best practice these days to separate Dev data from Prod data if all I have is a single Postgres instance? Any references to publicly available code examples would be hugely appreciated 🙏
1 replies