lucia: [Bug]: date.getTime() is not a function (originating in oslo) -> but the core problem is that nodejs-adapter from Lucia doesn't convert expiresAt as a date
Package
@lucia-auth/adapter-postgresql
Describe the bug
So my first time deep delving into the codebase of Lucia so bear with me:
- I first verified that
expires_at
is timestamp in the database with timezone. - When Lucia tries to validate the session it uses
this.adapter.getSessionAndUser(sessionId);
-> which will in turn go the database, fetch the session, convert thefields_with_underscores
tofieldsWithUnderscores
(ie.expires_at
->expiresAt
). - Next it will use
oslo
to check if the sessionisWithinExpirationDate
-> but theexpiresAt
has been loaded as astring
even though it is defined as a timestamp with zone.
I am using the following adapter for Postgres
const adapter = new NodePostgresAdapter(pool, {
user: 'auth_user',
session: 'session'
});
Here is how the database session looks like when loaded from the db by lucia.
{
userId: 'scp1x8lzy270qh5',
id: 'rqcui4nih4o6lix32xmxp1zzbukr6jp5qozm7m0q',
expiresAt: '2024-03-06 19:29:17.726+00',
attributes: {}
}
Here is the stack trace where it fails ultimately:
TypeError: date.getTime is not a function
at isWithinExpirationDate (file:///E:/Projects/my-project/node_modules/.pnpm/oslo@1.0.1/node_modules/oslo/dist/index.js:34:30)
This is a severe issue I can’t circumvent since upgrading (still in progress obviously) to v3. Any insight into this issue is more than welcomed. 🙏
About this issue
- Original URL
- State: closed
- Created 5 months ago
- Reactions: 2
- Comments: 18 (16 by maintainers)
For me, this is the solution: change the timestamp options.mode from “string” to “date”.
From this:
To this:
So the session table schema will look something like this:
Literally just hit this one as well 😅 Thanks @callmeberzerker Regarding https://github.com/lucia-auth/lucia/issues/1424#issuecomment-1947238448 I believe this is Drizzle intended behaviour (see https://github.com/drizzle-team/drizzle-orm/pull/1659)
@pilcrowOnPaper it might be worth fixing this at the adapter level or at the oslo level (accept string) as this could happen with other ORMs, not only Drizzle.
Something like this would work :
date instanceof new Date() ? new Date(date) : date
(I’m using this in a pnpm patch)I’ve encountered this as well and thank you for your contribution to the docs!
Oh wow, that’s sneaky. Yeah it should be probably mentioned in the docs - I guess at the top of the PostgreSQL database page.
After a lot of digging I found the source of my issue -> and I think the docs should warn of this.
If you use
drizzle
ORM in your project you must use theDrizzlePostgreSQLAdapter
as well, since the drizzle PostgreSQL driver will override the default handling(parsers) for several database types.See source code for
drizzle-orm
here:https://github.com/drizzle-team/drizzle-orm/blob/0da1cba84da08bc0407821c9ab55b3e780ff5e3f/drizzle-orm/src/node-postgres/driver.ts#L41
Mystery solved.
@pilcrowOnPaper shout if you agree on the docs and if you would accept a PR
Just a small update, I managed to checkout the Lucia repo -> and I can verify that the test works. Trying to find now what is the discrepancy between my project and the setup - or potentially some other
function
is being used in the production code that is not used by the test -> that forces theexpiresAt
to be marshalled asstring
.It’s Valentines Day so I guess I have nothing better to do. 🤣
Can you share your Drizzle/db schema? There’s also a new Drizzle adapter https://lucia-auth.com/database/drizzle