mjpearson / passport-slack Goto Github PK
View Code? Open in Web Editor NEWSlack OAuth2 strategy for Passport
License: MIT License
Slack OAuth2 strategy for Passport
License: MIT License
I was wondering why this module requires authentication every time I use it to log in, even if I am logged into slack.
Facebook passes the request straight thru.
Any ideas?
When using custom scopes, as proposed here, Slack returns the following error:
"Invalid permissions requested - Cannot request both identity scopes and other scopes at the same time"
For authentication with Slack, only identity.*
scopes can be used ; the doc section about using "custom scopes" should be modified accordingly.
See also : https://stackoverflow.com/questions/43300422/simultaneously-add-to-slack-and-sign-in-with-slack
It works as it should except that user is always asked for authorization even the slack app is already authorized. I tried with and without team parameter as well.
Slack has introduced new Slack apps and are now making them the default. New granular scopes rely on a completely new oauth endpoint . Read more at https://api.slack.com/authentication/oauth-v2
Are there any plans to upgrade this passport module to the new endpoint ?
Thanks!
When do you plan to release new version to npm? There are several useful things in the master
that would be good to have.
Also I've raised some PR's and would be great if you could review and merge them before relase if they fit.
Does slack support refresh tokens? The console.log(refreshToken)
line below returns undefined
. I notice that the general passport.js
docs indicate this might mean it's not offered by the provider. Drilling down into the slack docs makes it look like it was a feature at one point but no longer available. Just wondering if anyone can confirm that.
I saw some related topics for google Oauth but they appear to be strategy specific. The noted solutions did not work for me.
passport.use(
"slack",
new SlackStrategy(
{
clientID: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
scope: ["identity.basic", "identity.email", "identity.avatar"],
passReqToCallback: true,
},
async (req, accessToken, refreshToken, profile, done) => {
try {
console.log(refreshToken);
...
done(null, profile.user);
} catch (error) {
console.log(error);
}
}
)
);
Other similar Slack passport libraries allow passing a teamName
to the SlackStrategy config to make sure users can only authenticate through a specific team.
Is this possible through this library? I don't see it anywhere in documentation and have tried using teamName
and slackTeam
in the config but it does not work.
Slack has made some changes to the way display names work.
Currently this module simply sets display name to identity name like this profile.displayName = profile.user.name;
, but this change means that name
will always be the users "real name", and the customisable name is available as display_name
on the users profile.
I'm confused (and likely wrong) about the following ...
This isn't simply a matter of changing the way displayName
is set, because display name needs to be retrieved from a separate end point (I think?)
This module uses the variable name profile
, but fetches it from the users.identity
endpoint. There's another users.profile.get
endpoint which appears to contain the display_name
property.
Having said that, the user type object seems to contain all the desired information.
I followed every steps on how to implement this but for some reason I always get Cannot GET /auth/slack when I click the button on slack documentation
Stackoverflow question: http://stackoverflow.com/questions/43789719/passport-slack-return-cannot-get-auth-slack
I'm using this feature but it prompts the user for authorization every time they click the "Sign in with Slack" button. According to the documentation:
If the user is simply signing in to resume an existing relationship with your Slack app,
we'll send them to your redirect URL right away.
I also found a related Stack Overflow answer that recommends enabling your app for distribution.
@aoberoi I know this isn't necessarily an issue with this package, but is this information correct? If so, could the Slack API docs have a one-liner that describes this for future reference?
As a workaround, I mark this module as external and manually copy it into the build.
Removing this line will solve the issue:
https://github.com/mjpearson/passport-slack/blob/master/lib/passport-slack/index.js#L10
Here is full stack trace:
'TypeError: Path must be a string. Received undefined',
'at assertPath (path.js:28:11)',
'at Object.dirname (path.js:1349:5)',
'at Function.pkginfo.find (/opt/app/backend/.webpack/service/webpack:/node_modules/pkginfo/lib/pkginfo.js:89:1)',
'at Function.pkginfo.read (/opt/app/backend/.webpack/service/webpack:/node_modules/pkginfo/lib/pkginfo.js:115:1)',
'at module.exports (/opt/app/backend/.webpack/service/webpack:/node_modules/pkginfo/lib/pkginfo.js:66:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/webpack:/node_modules/passport-oauth/node_modules/passport/lib/passport/index.js:440:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/index.js:100534:30)',
'at __webpack_require__ (/opt/app/backend/.webpack/service/webpack:/webpack/bootstrap:19:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/webpack:/node_modules/passport-oauth/lib/passport-oauth/strategies/oauth.js:4:1)',
'at __webpack_require__ (/opt/app/backend/.webpack/service/webpack:/webpack/bootstrap:19:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/webpack:/node_modules/passport-oauth/lib/passport-oauth/index.js:4:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/index.js:99763:30)',
'at __webpack_require__ (/opt/app/backend/.webpack/service/webpack:/webpack/bootstrap:19:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/webpack:/node_modules/passport-slack/lib/passport-slack/strategy.js:5:1)',
'at __webpack_require__ (/opt/app/backend/.webpack/service/webpack:/webpack/bootstrap:19:1)',
'at Object.<anonymous> (/opt/app/backend/.webpack/service/webpack:/node_modules/passport-slack/lib/passport-slack/index.js:4:1)',
Unless this library upgrades to passport-oauth ^1.0.0 it will crash req.logIn(...)
when the app is using the latest version of Passport. This is caused by introducing lazy session initialization in passport 0.3.0. See the technical details and Jared's explanation.
Let me know if I can help.
Hi!
Slack introduced new scopes in the Oauth flow: identity.basic, identity.email.
https://api.slack.com/methods/users.identity
With these you don't have to allow access to all the team users (users:read), just identify yourself.
Unfortunately this library cannot handle it yet (Scope 'users:read' is required to retrieve Slack u
ser profile + returns with [Object object] instead of the user).
It would be nice to update the lib :)
Thanks
Hi @aoberoi, it looks like you are the current maintainer of this project. I incorrectly emailed @mjpearson earlier today (after finding his email still listed on the NPM description page).
If this project is no longer of direct relevance to you, I would love to take over maintainership of it. I work on TS/JS and have the need to authenticate several projects against Slack. I have a history of submitting PRs of varying sizes to open-source projects, have spent the last several years in the TS/JS ecosystem professionally, and write most of my side projects in the language too.
In the past, albeit over a decade ago, I was maintainer of a project used on ~3k server installations that provided an in-CMS package manager for Drupal 6 (The module, Plugin Manager, was retired a few years after release when the functionality was integrated into the next major release of the platform), so maintainership is something that I understand the cost of.
ReferenceError: json is not defined at: lib/passport-slack/strategy.js
Hi,
I am trying to send a callback url to the passport oAuth but 'callbackURL' comes back as unspecified
I want to provide this module with typing support so i opened a pr over at DefinitelyTyped
but the version
in package.json
has to be >= 1.0.0
or should i make a pull request over here adding the typings
I implemented the example in the documentation as follows:
router.get('/auth',
passport.authorize('slack'));
router.get('/auth/callback',
passport.authorize('slack', { failureRedirect: '/login' }),
function(req, res) {
console.log("TEST");
// Successful authentication, redirect home.
res.redirect('/slack');
});
I was able to successfully request permissions from slack and return the the /auth/callback endpoint. However, after that point I would receive a 500 error of "missing_scope".
My strategy looks as follows:
passport.use(new SlackStrategy({
//TODO this needs to not be in the .js
clientID: "CLIENT",
clientSecret: "SECRET",
scope: 'identify channels:read channels:history reactions:read'
},
function(accessToken, refreshToken, profile, done) {
User.findOrCreate({ SlackId: profile.id }, function (err, user) {
return done(err, profile);
});
}
));
I was able to track it down to the oauth2 library loading the profile on the auth callback. However, I didn't have the required scope slack needed to allow me to do that. After adding the users:read
scope, I was able to successfully retrieve my access token and user.
Not sure if an internal change is required or it's merely a matter of citing that users:read
is required as a scope for the access token function to work.
As per the slack API documentation (https://api.slack.com/docs/oauth see section "Bot user access tokens"), when a bot created, the JSON payload should return the access token along with the bot user access token. However, we only get the accessToken. Is there a way to get both tokens by adding a parameter to the Oauth flow?
I'm currently using the slack sign button to authenticate. My express server currently contains this:
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
// https://github.com/mjpearson/passport-slack
passport.use(new SlackStrategy({
clientID: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
},
(accessToken, refreshToken, profile, done) => {
console.log('profile!!', profile)
done(null, profile);
}));
app.use(passport.initialize());
app.use(passport.session());
app.get('/auth/slack', passport.authenticate('slack'));
app.get('/auth/slack/callback',
passport.authenticate('slack', { successRedirect: '/', failureRedirect: '/login' }));
When I sign in however, profile return this: { ok: false, error: 'invalid_auth' }
I do still get redirected to home meaning the authentication worked but I am not able to retrieve the user data.
I saw that invalid_auth is related to Standard failure response when used with an invalid token
What am I doing wrong?
just ran into an issue with our code where we we're using the profile.provider value instead of 'slack' like everywhere else in our code.
the doc string on the Strategy.prototype.userProfile
function says:
* This function constructs a normalized profile, with the following properties:
*
* - `provider` always set to `slack`
* - `id` the user's ID
* - `displayName` the user's username
however, the provider field actually get set to Slack
. Maybe this is correct based on what slack returns, in which case the doc string should get changed though?!
/**
* Retrieve user profile from Slack.
*
* This function constructs a normalized profile, with the following properties:
*
* - `provider` always set to `slack`
* - `id` the user's ID
* - `displayName` the user's username
*
* @param {String} accessToken
* @param {Function} done
* @api protected
*/
Strategy.prototype.userProfile = function(accessToken, done) {
//this._oauth2.useAuthorizationHeaderforGET(true);
var self = this;
this.get(this.profileUrl, accessToken, function (err, body, res) {
if (err) {
return done(err);
} else {
try {
var json = JSON.parse(body);
if (!json.ok) {
done(json);
} else {
var profile = {
provider: 'Slack'
};
profile.id = json.user_id;
profile.displayName = json.user;
profile._raw = body;
profile._json = json;
// if extended user profile is not required, return what we already have
if(!self.extendedUserProfile) {
return done(null, profile);
}
// otherwise call for more detailed profile (requires users:read scope)
self.get(self.userInfoUrl + profile.id + "&token=", accessToken, function (err, body, res) {
if (err) {
return done(err);
}
var infoJson = JSON.parse(body);
if (!infoJson.ok) {
done(infoJson);
}else{
profile._json.info = infoJson;
done(null, profile);
}
});
}
} catch(e) {
done(e);
}
}
});
}
Hi @mjpearson, I saw the note in your README about how you could use some help and I'd like to discuss what you have in mind. Thanks for carrying this package forward for as long as you have. It's clear that you put a lot of care and work into it.
My name is Ankur and I work on developer tools at Slack. Our team builds and maintains packages and tools in collaboration with the community. OAuth plays a pretty critical role in how developers deal with user identity in their app (Sign in with Slack) and handle installation (Add to Slack) - and we think this package is important to how developers implement these features.
I've got a little bit of experience working with passport, OAuth, and Slack's APIs. I maintain another implementation of a Slack passport strategy. I'd be excited to help, in almost any way that you are open to. There's also an opportunity to deliver the next generation of this package in a way that supports workspace apps as a first class citizen.
Here's what my vision looks like: I'd like to triage the current open issues and pull requests so we make sure we know what users of this package need. Next, we create a plan to merge my implementation with this one. Maybe we write some tests. Finally, if you're comfortable with it, we can take lead by moving this repo over to the slackapi
github organization and we could gain publish access to the passport-slack
package on npm.
If you want to chat outside of this issue, feel free to email me: [email protected]
Hey! Running into an error in production. Seems to be affecting a few slack accounts.
Sentry (error logging) is reporting a Reference Error json is not defined
here:
json is indeed not defined anywhere, what what ment to be returned here?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.