foal
foal copied to clipboard
[Authentication] the `fetchUser` functions and `FetchUser` type can be confusing
Issue
This interface and these functions exist to populate the ctx.user
property in the @UseSessions
and @JWTxx
hooks.
There are some problems with them:
- These functions are additional code to maintain.
- It is not straightforward to understand what the
FetchUser
interface and thefetchUser
function (orfetchMongoDBUser
,fetchUserWithPermissions
) are. - They give the impression that the framework is closely coupled with TypeORM. When we want to use another ORM, we have to figure out what the
fetchUser
function are, what their behavior is and how to re-implement them.
They actually just do a User.findOne
at this end.
Solution
Remove these functions and the interface and replace them with these (examples with TypeORM):
Sessions
// Before
@UseSessions({
user: fetchUser(User)
})
// After
@UseSessions({
user: (id: number) => User.findOneBy({ id })
})
// Or user IDs should be strings
@UseSessions({
user: (id: string) => User.findOneBy({ id }),
userIdType: 'string'
})
JWT
// Before
@JWTRequired({
user: fetchUser(User)
})
// After
@JWTRequired({
user: (id: number) => User.findOneBy({ id })
})
// Or user IDs should be strings
@JWTRequired({
user: (id: string) => User.findOneBy({ id }),
userIdType: 'string'
})
With permissions
// Before
@UseSessions({
user: fetchUserWithPermissions(User)
})
// After
@UseSessions({
user: (id: number) => User.findOneWithPermissionsBy({ id })
})
The hooks will automatically check and convert the user ID types if necessary and so will work well with ORM with a strict policy on JS and TS types for their functions.
Resolved in v3