passport-magic-login icon indicating copy to clipboard operation
passport-magic-login copied to clipboard

Property 'callbackUrl' does not exist on type 'MagicLoginStrategy'.

Open Goddak opened this issue 4 months ago • 0 comments

The current readme reads;

"Once you've got that, you'll then need to add a couple of routes to your Express server:"

// This is where we POST to from the frontend
app.post("/auth/magiclogin", magicLogin.send);

// The standard passport callback setup
app.get(magicLogin.callbackUrl, passport.authenticate("magiclogin"));

However this is a broken example as we get the error; Property 'callbackUrl' does not exist on type 'MagicLoginStrategy'.ts(2339) image

callbackUrl exists on the options interface but this is private on the MagicLoginStrategy class:

import { Request, Response } from 'express';
import { SignOptions } from 'jsonwebtoken';
import { StrategyCreatedStatic } from 'passport';
declare type VerifyCallback = (payload: any, verifyCallback: (err?: Error | null, user?: Object, info?: any) => void, req: Request) => void;
interface Options {
    secret: string;
    callbackUrl: string;
    jwtOptions?: SignOptions;
    sendMagicLink: (destination: string, href: string, verificationCode: string, req: Request) => Promise<void>;
    verify: VerifyCallback;
    /** @deprecated */
    confirmUrl?: string;
}
declare class MagicLoginStrategy {
    private _options;
    name: string;
    constructor(_options: Options);
    authenticate(this: StrategyCreatedStatic & MagicLoginStrategy, req: Request): void;
    send: (req: Request, res: Response) => void;
    /** @deprecated */
    confirm: (req: Request, res: Response) => void;
}
export default MagicLoginStrategy;

So either:

  • The docs are wrong and there's a new approach to this

Or

  • the class needs a little update

I'm voting duff docs as a little poke in the file history shows me that options has always been private :man_shrugging:

I managed to get this working by just not using it..

router.get('/magiclogin/callback', 
  passport.authenticate("magiclogin"),
  (req: Request, res: Response, next: NextFunction) => {
    res.status(200).json({ user: req.user });
    next();
  }
);

It'd probably also be worth mentioning serializeUser and deserializeUser functions in the docs, initially I thought I could exclude them by some magic, fortunately I've used passport before, newer users may come unstuck.

passport.serializeUser(function(user, cb) {
  process.nextTick(function() {
    cb(null, user);
  });
});

passport.deserializeUser<IUser>(async function(user, cb) {
  const dbUser = await User.findOne({ email: user.email }).exec()
  process.nextTick(function() {
    console.log('deserialized user', dbUser)
    return cb(null, dbUser);
  });
});

Goddak avatar Mar 05 '24 18:03 Goddak