node-saml / passport-saml

SAML 2.0 authentication with Passport

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Readme is wrong

MickL opened this issue · comments

The readme shows the following example:

passport.use(
  new MultiSamlStrategy(
    {
      passReqToCallback: true, // makes req available in callback
      getSamlOptions: function (request, done) {
        findProvider(request, function (err, provider) {
          if (err) {
            return done(err);
          }
          return done(null, provider.configuration);
        });
      },
    },
    function (req, profile, done) {
      // for signon
      findByEmail(profile.email, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    },
    function (req, profile, done) {
      // for logout
      findByNameID(profile.nameID, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    }
  )
);

But this doesnt seem to be valid JavaScript. All three parameter contain a function within a function:

function (request, done) {
            findProvider(request, function (err, provider) {

Further the example shows new SamlStrategy() and new MultiSamlStrategy() with three arguments but according to the TypeScript interface the constructor only accepts two arguments. In this case I wonder if the Typings are wrong or the readme.

Bildschirm­foto 2022-11-10 um 16 11 50

Where are you seeing this problem? This is the code I see in master:

export class MultiSamlStrategy extends AbstractStrategy {
static readonly newSamlProviderOnConstruct = false;
_options: SamlConfig & MultiStrategyConfig;
constructor(
options: MultiStrategyConfig,
signonVerify: VerifyWithRequest,
logoutVerify: VerifyWithRequest
);
constructor(
options: MultiStrategyConfig,
signonVerify: VerifyWithoutRequest,
logoutVerify: VerifyWithoutRequest
);
constructor(options: MultiStrategyConfig, signonVerify: never, logoutVerify: never) {
if (!options || typeof options.getSamlOptions !== "function") {

Sorry I have installed passport-saml instead of @node-saml/passport-saml because this is what the Readme told me to do:

https://github.com/node-saml/passport-saml/blob/master/README.md

Very confusing. Readme should be updated, I do a PR :)

Anyway this doesnt make sense to me, this is no valid JS/TS or is it?

function (profile, done) {
      // for signon
      findByEmail(profile.email, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    },
    function (profile, done) {
      // for logout
      findByNameID(profile.nameID, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    }

You're right, that isn't valid JS or valid TS. I'm not sure where you got that, it doesn't seem to me that it is in the README. The MultiSamlStrategy is a constructor that takes three arguments, one is an object, and two are functions. I'm not sure what your outer function there is referencing.

This has been copied from the readme:

passport.use(
  new SamlStrategy(
    {
      path: "/login/callback",
      entryPoint:
        "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php",
      issuer: "passport-saml",
      cert: "fake cert", // cert must be provided
    },
    function (profile, done) {
      // for signon
      findByEmail(profile.email, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    },
    function (profile, done) {
      // for logout
      findByNameID(profile.nameID, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    }
  )
);

I just want to point out the point that doesnt seem to be valid code to me:

function (profile, done) {
      // for logout
      findByNameID(profile.nameID, function (err, user) {
        if (err) {
          return done(err);
        }
        return done(null, user);
      });
    }

Maybe you meant to exectue a already defined function findByNameID which takes nameID AND another function into it. Very confusing IMO, personally I would make the example more simple or just add comments would make it more clear to me:

passport.use(
  new SamlStrategy(
    {
      path: "/login/callback",
      entryPoint:
        "https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php",
      issuer: "passport-saml",
      cert: "fake cert", // cert must be provided
    },
    function (profile, done) {
      // for signon
    },
    function (profile, done) {
      // for logout
    }
  )
);

I see what you are saying now. I'll have a look and put up a PR with something clearer.

I put up a PR #811 , maybe you like it :)

@MickL , perhaps the changes I've made to the README here will help clear things up.

If so, feel free to close this and #811.

You didnt change the example that confused me a lot. I think #811 would make it way more easy to understand but I can close it if you dont like it.

I agree that node-saml and passport-saml shouldnt contain duplicate informations. I was thinking node-saml can be used without passport and passport-saml is just a wrapper to make it work with passport.

The code you propose in #811 returns a variable that isn't in scope, user, which makes it invalid JS. This proposal adds information explaining how it is supposed to work. Basically, you just have to implement those functions yourself and call the callback in the standard Node-back pattern.

I was thinking node-saml can be used without passport and passport-saml is just a wrapper to make it work with passport.

This is entirely true, and I think we have a lot of README updates to make this clear. Feel free to offer suggestions along these lines.

Yes the // ... means "implement your own code". Using named functions that also require another function to put in makes it super confusing IMO. I will close everything tho as you dont like it.

I see that; so one type of unclear which isn't syntactically valid vs. another type of unclear that references unseen code; pick your poison I guess 🤷‍♂️