Session guard: remember-me requires a Lucid model
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 222
- Forks
- 70
- PR merge metrics
- No merged PRs in 30d
Description
TL;DR
The session guard works fine with a custom, non-Lucid user provider, but remember-me does not: `DbRememberMeTokensProvider` is the only token store that ships, and it requires a Lucid model both in its types (`tokenableModel: TokenableModel extends LucidModel`) and at runtime (`user instanceof model`, `user.$primaryKeyValue`, `model.$adapter`). There is no non-Lucid database implementation to copy, and the docs never mention that one is possible. Could it take a query client plus a `getUserId` accessor instead?The Issue
I'm using the session guard with a custom user provider because my app's user model isn't a Lucid model — it comes from my own ORM. That part works fine: sessionGuard({ useRememberMeTokens: false, provider }) accepts any SessionUserProviderContract<unknown>, and the custom-guard guide documents exactly this setup with its Prisma example ("a Lucid-based provider would return a model instance, while a Prisma-based provider would return a Prisma user object"). Login, logout and session restoration all work.
Switching remember-me on is where it falls over. The only token store that ships is DbRememberMeTokensProvider, and it expects the user to be a real Lucid model — in its types and in the code that runs:
// types
export type DbRememberMeTokensProviderOptions<TokenableModel extends LucidModel> = { tokenableModel: TokenableModel, ... }
export interface RememberMeTokensProviderContract<Tokenable extends LucidModel> { ... }
// runtime, DbRememberMeTokensProvider
if (user instanceof model === false) throw new RuntimeException(`Invalid user object. It must be an instance of the "${model.name}" model`)
if (!user.$primaryKeyValue) throw new RuntimeException(...)
async getDb() { return model.$adapter.query(model).client }
So forModel(...) doesn't type-check against my model, and if I cast around the types it fails at runtime because my model has no $adapter. The only way through would be to implement SessionWithTokensUserProviderContract myself, and while that is technically enough — the framework's own test suite implements it in factories/session/main.ts — that one is in-memory and marked "should not be exported to the outside world", so there is no database implementation to learn from.
What makes this frustrating is that the docs give the impression a Lucid model is required. Remember-me appears in exactly one shape:
static rememberMeTokens = DbRememberMeTokensProvider.forModel(User) // on the Lucid BaseModel
and neither the session guard guide nor the custom-guard guide mentions that a non-Lucid user provider is supported, that useRememberMeTokens: false is the way to configure one, or that SessionWithTokensUserProviderContract exists at all.
Ask
Could DbRememberMeTokensProvider be made model-agnostic? It only really needs a query client and a way to read a user's id, so something like:
{ client: () => Promise<QueryClientContract>, getUserId: (user: RealUser) => string | number | BigInt, table?, tokenSecretLength? }
instead of tokenableModel, with the extends LucidModel bound dropped from RememberMeTokensProviderContract. That shouldn't be breaking — forModel(User) could stay as a thin Lucid wrapper, and the rest of the class is already data-layer neutral: dbRowToRememberMeToken, verify and recycle only ever need a query client.
If that's out of scope, documenting the non-Lucid path would already help a lot.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with DbRememberMeTokensProvider and the SessionWithTokensUserProviderContract, then compare the in-memory implementation in factories/session/main.ts with the custom-guard and session-guard guides. Determine the supported non-Lucid API and update the provider, its types, tests, and documentation so remember-me works or its limitations are explicit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authentication
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100