-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support promises flow #536
Comments
Since #225 and #243 have been created, it seems that a lot of people have been using promises and It's possible to promisify |
@jaredhanson What are your thoughts on introducing Promise support now that using Promises and |
👍 |
@jaredhanson If I could reply to your sentiment about promises mentioned in your Stack Overflow answer from 2012:
I'd say that given the new Any decent, modern programming language with parallelism built in, and even old ones with parallelism tacked on, use Promises or Futures. Wikipedia has a list of languages that implement Promises, which includes the following languages with native Promise support: C++, Dart, Java, JavaScript, C#, Python, R, Scala, Swift, and Visual Basic, and more. If you don't want to force Promises on your users, it would make sense to make a new major version of the Passport API while still fixing bugs in the old version. Using a real concurrency construct like Promises should be the way forward for any Node.js library. |
Just to note, Promises and callbacks aren't necessarily exclusive, you can support both in one function: const asyncFunc = (callback) => {
const doAsyncThing = (cb) => {/* Do something asynchronous here, then call cb() */};
if (!callback) {
return new Promise(resolve => doAsyncThing(resolve));
} else {
doAsyncThing(callback);
}
} Now both of these work, which means this would only be a feature release rather than a major release since it doesn't break anybody! asyncFunc(() => { /* Callback when finished */ });
asyncFunc()
.then(() => { /* Resolve promise when finished */ }); |
@jaredhanson Do you have any thoughts on adding promise support to Passport? |
Any update on this? It would make everything so much cleaner! |
Has any one tried to use the new |
I tried using the Someone should just fork the project and support promises. |
What benefits would promises offer an application built on Express, using the middleware pattern? For example, passport is used via middleware like:
Why does that need to return a promise? |
I am using express with graphql. So, I am using passport to secure my graphql endpoint but the issue is that graphql only works with promises and so it becomes necessary to wrap functions like Also, most of the JS community (browser & node) is definitely moving fast towards adoption of |
@jaredhanson Also, re: middleware, Express 5 is going to have explicit promises support. |
Someone needs to PR with an alternate interface |
@mikemaccana Where did you read that? |
@zenflow Yeah, because they are already supported (somehow) in 4.x: |
+1 for native promise support |
@michaelwalloschke Hmm, using promises is definitely advocated, but it doesn't look like there's built-in support... Note that the second example under your link uses a
|
This looks like the |
@jaredhanson Mongoose and Sequelize prefer promises over callbacks now, so in a // strategy.js
...
User.findOne({ where: { email })
.then((existingUser) => { throw new myUserExistsError(`user with email ${email} already exists`; })
.then(() => User.create(userData))
.then(newUser => done(null, newUser, { message: 'success' })
.catch((error) => {
if (error instanceof myUserExistsError || error instanceof Sequelize.UniqueConstraintError) {
return done(error, false, { message: 'user already exists' } );
}
return done(error, false, { message: 'some other error' } );
});
...
// handler.js
(req, res, next) => {
return passport.authenticate('local-signup', (error, user, info) => {
if (error) return res.status(400).json({ message: info });
if (user) return res.status(200).json({ message: info });
return res.status(401).json({ message: info });
}
})(req, res, next); where passport.authenticate can only accept a callback, making this a |
lol I think |
@zenflow See expressjs/express#2237, the Express 5 release tracking bug list. Top item:
if you follow it, you'll end up at Router 2.0 which is pillarjs/router#60 |
Await is way better than endless chaining and has been supported for a long time, it has my vote |
Agreed. It would be only natural for Passport.js to support it as well, also given the growing demand |
As of today passport's done() is the only oldschool error handling artifact in my app. It seems that everyone else moved to promises. |
Are you referring to |
I'm referring to LocalStrategy example where we pass errors to done(). In my app I have calls to database and async password hashing inside that callback which both return promises so if I only knew a way to make passport return a promise too I could get rid of done() and make it all look uniform. Does this make sense? |
I thought about it all day- I've read entire documentation over and over again and it finally makes sense to me why you went with done() to cover all the possible outcomes as described in Verify Callback. As much as I wish there was a simpler way to do this I'm afraid that I can't come up with a more elegant solution that would work in Express 4.x. It looks like one may be possible in Express 5.x. Sorry for wasting your time! |
@jaredhanson is this issue on your radar? |
I think one of the best arguments is how this can simply building unit tests. This article by Gustaf Holm shows how promises and async / await simply test code, and make it easier to write code that is easy to test. |
Jared works at Auth0 now, and hasn't made any meaningful commits to this repo in forever. He does auth programming all day—for money. Why do you guys expect him to swoop in and save the day? Passport doesn't seem like it's doing a ton of stuff. Maybe it's time for another hero to rise up and make some auth library from scratch? Then again, it seems everyone could just use https://nodejs.org/api/util.html#util_util_promisify_original where needed. |
@corysimmons - or someone(s) here could make more PRs on this lib. Do you think @jaredhanson would be able/willing to review PRs still? If that's a no-go, what's better/more-active than passport in the js auth space? |
This is an open source project. If @jaredhanson wanted to chime in here, he's had close to two years to do it. If there's a reasonable fix to this, someone should feel free to fork the project. |
Project has an MIT license. There's no legal impediment to forking this. Moreover there are more than 20 pending PRs. Might make sense to review those PRs. If enough of us are interested, we can decide on where we want to do development, see if the PRs transfer where relevant, and restart development. |
@torenware - there's some sense in what you say, but if he's going to let it go, given its popularity the responsible thing would be to turn it and the npm package over to a maintainer, or grant shared access at least. That's easier than ever to do now with github and npm having tools for that. |
We've already forked it here https://github.com/passport-next/passport and we want to add promises, passport-next#7 if you want to contribute to the fork I'd be happy to look at any PRs. |
I have an issue related to async behaviour in passport - https://stackoverflow.com/questions/56389077/passport-azure-ad-seems-to-run-asynchronously. When run as normal middleware:
Like this in the https://tsed.io framework I am using. That is equivalent to the proverbial:
Then it works fine. However you can also run it as a detached middleware. Something like:
But this doesn't work. As discussed in the referenced Stackoverflow Question, the I don't understand enough about Passport to know why it is only a problem when detached. Though if Passport returned a promise then the azure people could re-write this to wrap that |
The standard lib of Node.js is on a journey to create promise-based implementations of their APIs. Modules such as: One can even compare prominent modules such as In 2022 it seems async/await is the defacto future. With all respect towards this amazing library, I do hope it is time to consider implementing promise-based versions of all functions. It would be a great step forward to a cleaner code base for many users. |
I'm using this workaround to convert import { promisify } from "node:util";
import passportHttpRequest from "passport/lib/http/request.js";
// Workaround: Convert to promises before passport.initialize()
app.use(function (req, res, next) {
req.logIn = promisify(passportHttpRequest.logIn);
req.logOut = promisify(passportHttpRequest.logOut);
next();
});
app.use(passport.initialize());
app.use(passport.session());
app.get("/login", async function (req, res, next) {
try {
const user = { id: "1234" };
await req.login(user, { keepSessionInfo: true });
res.send("LOGGED IN");
} catch (err) {
return next(err);
}
});
app.get("/logout", async function (req, res, next) {
try {
await req.logout({ keepSessionInfo: true });
res.send("LOGGED OUT");
} catch (err) {
return next(err);
}
}); |
Return promise from all api method for work with passport via await/yield/then/(without callback) flow.
It will be nice! All new modules uses async/await now via babel or nodejs 7. It really more simple and clean.
The text was updated successfully, but these errors were encountered: