Preserve .length parameter for verification callback
egormkn opened this issue · comments
I'm submitting a...
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Current behavior
Currently nestjs/passport uses the rest parameters syntax when it wraps verification callback. Passport strategies that are calling this callback could not determine the number of arguments that callback expects, because verify.length
returns 0.
Expected behavior
verify.length
in strategy constructors should be equal to validate.length
in NestJS PassportStrategy implementation.
Minimal reproduction of the problem with instructions
import { Strategy } from 'passport-vkontakte';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
@Injectable()
export class VkontakteStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
clientID: 123,
clientSecret: '456',
callbackURL: 'http://localhost:3000/auth/vkontakte/callback',
});
}
async validate(accessToken: string, refreshToken: string, params: string, profile: any): Promise<any> {
return profile;
}
}
This implementation of passport-oauth2 strategy throws an exception before calling validate
.
What is the motivation / use case for changing the behavior?
It seems that almost every passport strategy assumes that the callback that is passed into its constructor has .length
property, that represents a number of arguments the callback receives. Breaking this assumption may lead to various bugs. For example, I've encountered a bug with passport-vkontakte, where an exception is thrown when verify.length < 4
. Even passport-oauth2 library checks for length parameter so that should be considered as a bug in nestjs/passport rather than a bug in a particular strategy.
Environment
Nest version: 7.5.1
Node version: 14.15.0
Would you like to create a PR for this issue?
Actually I can't figure out how to resolve this properly. It seems that when MixinStrategy calls super
constructor we can't access this.validate
as the class was not instantiated yet.
Could you please look at this? I'm more of a beginner and have much less experience with typescript
Locally this problem could be solved by passing callback function directly as a second constructor argument. MixinStrategy then adds wrapped callback as a third constructor argument that is just not used later by the passport strategy. However I think that there should be better solution so that others do not have to figure it out themselves and google this issue to fix related bugs.
I've found a solution and will create a PR soon
Fixed in 7.1.1. More on that here #435 (comment)
Thanks for your efforts!