auth0 / passport-linkedin-oauth2

Passport Strategy for LinkedIn OAuth 2.0
MIT License
119 stars 107 forks source link

[Unhandled error]AuthorizationError: The user cancelled the authorization #90

Open kunalk16 opened 2 years ago

kunalk16 commented 2 years ago

Please do not report security vulnerabilities here. The Responsible Disclosure Program details the procedure for disclosing security issues.

Thank you in advance for helping us to improve this library! Please read through the template below and answer all relevant questions. Your additional work here is greatly appreciated and will help us respond as quickly as possible. For general support or usage questions, use the Auth0 Community or Auth0 Support. Finally, to avoid duplicates, please search existing Issues before submitting one here.

By submitting an Issue to this repository, you agree to the terms within the Auth0 Code of Conduct.

Description

Provide a clear and concise description of the issue, including what you expected to happen. When the user logs in but denies to give permission to the app to access linkedin data, there is an unhandled error thrown that causes a 500. image Stacktrace: at LinkedinAuthStrategy.OAuth2Strategy.authenticate (C:\a\b\node_modules\passport-oauth2\lib\strategy.js:138:25) at attempt (C:\a\b\node_modules\passport\lib\middleware\authenticate.js:369:16) at authenticate (C:\a\b\node_modules\passport\lib\middleware\authenticate.js:370:7) at C:\a\b\node_modules\@nestjs\passport\dist\auth.guard.js:96:3 at new Promise () at C:\a\b\design-platform-backend\node_modules\@nestjs\passport\dist\auth.guard.js:88:83 at MixinAuthGuard. (C:\a\b\node_modules\@nestjs\passport\dist\auth.guard.js:49:36) at Generator.next () at fulfilled (C:\a\b\node_modules\@nestjs\passport\dist\auth.guard.js:17:58) at processTicksAndRejections (node:internal/process/task_queues:96:5)

Reproduction

Detail the steps taken to reproduce this error, what was expected, and whether this issue can be reproduced consistently or if it is intermittent. It can be reproduced consistently.

  1. Login to linkedin
  2. Instead of allowing permission, press cancel image
  3. We get a 500 with the stacktrace: at LinkedinAuthStrategy.OAuth2Strategy.authenticate (C:\a\b\node_modules\passport-oauth2\lib\strategy.js:138:25) at attempt (C:\a\b\node_modules\passport\lib\middleware\authenticate.js:369:16) at authenticate (C:\a\b\node_modules\passport\lib\middleware\authenticate.js:370:7) at C:\a\b\node_modules\@nestjs\passport\dist\auth.guard.js:96:3 at new Promise () at C:\a\b\design-platform-backend\node_modules\@nestjs\passport\dist\auth.guard.js:88:83 at MixinAuthGuard. (C:\a\b\node_modules\@nestjs\passport\dist\auth.guard.js:49:36) at Generator.next () at fulfilled (C:\a\b\node_modules\@nestjs\passport\dist\auth.guard.js:17:58) at processTicksAndRejections (node:internal/process/task_queues:96:5)

Environment

Please provide the following:

Strategy code:

@Injectable()
export class LinkedinAuthStrategy extends PassportStrategy(Strategy, 'linkedin') {
    constructor() {
        super({
            clientID: '<clientID>',
            clientSecret: <secret>,
            callbackURL: <url>,
            scope: ['r_emailaddress', 'r_liteprofile'],
        });
    }

    validate(accessToken: string, refreshToken: string, profile: Profile, done: Function): void {
        const { name, emails, photos } = profile;
        const user = {
            email: emails[0]?.value,
            firstName: name.givenName,
            lastName: name.familyName,
            picture: photos[0]?.value,
        };

        done(null, user);
    }
}
RedRosh commented 1 year ago

For anyone facing this error, you can handle it in NestJs by adding a filter on top of the controller function:

@Get("linkedin/callback")
@UseGuards(LinkedinAuthGuard)
@UseFilters(new UnauthorizedFilter()) // <--- HERE
linkedinCallback(@LoggedUser() user: User, @Res() res: Response) {

    const clientUrl = ".....";
    res.redirect(clientUrl);
}

to implement the filter:

    @Catch(UnauthorizedException)
export class UnauthorizedFilter implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();

        // Get the error message from the exception if available
        const errorMessage = exception?.message || "Unauthorized";

        // Do something with the error
        response.redirect(CLIENT_URL);
    }
}