lucia-auth / lucia

Authentication, simple and clean
https://lucia-auth.com
MIT License
9.46k stars 485 forks source link

[Feature Request]: The type of user_id can be specified as the user wants #1366

Closed lxia1220 closed 7 months ago

lxia1220 commented 8 months ago

Package

lucia

Description

lucia currently only supports string type user_id, making it difficult to apply to systems using other types. To apply, you must create a separate table (ex: lucia_user) or need to create a separate adapter for typings.

The point of discussion here is how to retrieve the corresponding type from the user. Here are a few ways I've thought of it:

The above two methods are easy to implement, but there is a problem in that it is difficult to know what the generic means.

Another way is to provide an interface that can be defined.

interface BaseUser {} // Provides an interface that can be overridden

declare module "lucia" { 
    interface BaseUser { // Write it in the desired type
        id: number;
    }
}

export interface User extends UserAttributes {
    id: BaseUser extends { id: infer U } ?  U : string; // fallback it to string for backward
}

async function createSession(
    userId: User["id"], // use userId types
        // ^?  (parameter) userId: number
    ) {

}

It's intuitive, but when using two or more Lucia, you cannot use different types.

I'd like to hear opinion on this

tobiasdiez commented 8 months ago

Note that the session also has a reference to the userId, so the type of that would need to be changed as well.

In my opinion, the combination of both approaches is the most flexible: add generics on lucia and their adapters to specify the complete type of a user and session. So the usage would look like:

interface User {
  id: number
  name: string
  otherProperties...
}
interface Session {
   id: number
   expiresAt: Date
   userId: number
   otherProperties...
}

const lucia = new Lucia<User, Session>(new Adapter(db));

Internally, the Lucia constructor then typechecks that user has an id and that the session has id, expiresAt and the few other fields that Lucia needs (perhaps Lucia could expose a BaseSession interface that one could extend). In addition, type-aware adapters (eg prisma) could typecheck that the db conforms to the User and Session interface (after taking the getSession/UserAttributes methods into account).

frederichoule commented 8 months ago

That feature would be really helpful, especially the way @tobiasdiez propose.

McPizza0 commented 8 months ago

I've added a $50 bounty on this issue with Algora. If the maintainers would like to accept it, here's the invitation.

what the bounty covers:

cupcakearmy commented 8 months ago

would second that,would you accept prs for this?

aguynamedben commented 7 months ago

+1, just ran into this

image image
MickL commented 7 months ago

Same issue, because in PostgreSQL (which I use with Drizzle ORM) I want to chose type SERIAL which is probably the most common type for ids. Postgres does then use autoincrement integer values:

export const user = pgTable('user', {
  id: serial('id').primaryKey(),
  email: varchar('email', { length: 256 }).unique(),
  hashedPassword: varchar('hashed-password', { length: 256 }),
});

I dont want to set the id with generateId(), as shown in the docs, when the database already has an autoincrement feature with uniqueness.

HelixHEX commented 7 months ago

would second that,would you accept prs for this?

Unfortunately they aren't. I cloned both the lucia package as well as the prisma adapter package and manually changed the types to accept both string and id types since I can't change schema.

pilcrowonpaper commented 7 months ago

If you guys missed it, we added an option to change the user ID type in the latest version of Lucia :D

Sorry it took a while!

chizuoka commented 4 months ago

If you guys missed it, we added an option to change the user ID type in the latest version of Lucia :D

Sorry it took a while!

Awesome. Was looking for this... May I know where the documentation for this is.

dslingr commented 4 months ago

If you guys missed it, we added an option to change the user ID type in the latest version of Lucia :D Sorry it took a while!

Awesome. Was looking for this... May I know where the documentation for this is.

https://lucia-auth.com/basics/users

Bottom of the page.

Pundima-Lakshan commented 1 month ago

Same issue, because in PostgreSQL (which I use with Drizzle ORM) I want to chose type SERIAL which is probably the most common type for ids. Postgres does then use autoincrement integer values:

export const user = pgTable('user', {
  id: serial('id').primaryKey(),
  email: varchar('email', { length: 256 }).unique(),
  hashedPassword: varchar('hashed-password', { length: 256 }),
});

I dont want to set the id with generateId(), as shown in the docs, when the database already has an autoincrement feature with uniqueness.

Hi same issue, is there any workaround for this other than changing the schema

davidmgrana commented 3 weeks ago

Did anyone got this to work? i was not able to

vladshcherbin commented 3 weeks ago

It does work, I've already used it in projects just the way it's mentioned in the docs