Initial commit
This commit is contained in:
commit
8e79fee52f
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
npm-debug.log*
|
89
README.md
Normal file
89
README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# passport-icynet
|
||||
|
||||
Passport strategy for authentication with [Icy Network](https://icynet.eu) through the OAuth 2.0 API.
|
||||
|
||||
## Usage
|
||||
`npm install passport-icynet --save`
|
||||
|
||||
#### Configure Strategy
|
||||
The Icy Network authentication strategy authenticates users via a Icy Network user account and OAuth 2.0 token(s). A Icy Network API client ID, secret and redirect URL must be supplied when using this strategy. The strategy also requires a `verify` callback, which receives the access token and an optional refresh token, as well as a `profile` which contains the authenticated Icy Network user's profile. The `verify` callback must also call `cb` providing a user to complete the authentication.
|
||||
|
||||
```javascript
|
||||
var IcyNetworkStrategy = require('passport-icynet').Strategy;
|
||||
|
||||
var scopes = ['image', 'email'];
|
||||
|
||||
passport.use(new Icy NetworkStrategy({
|
||||
clientID: 'id',
|
||||
clientSecret: 'secret',
|
||||
callbackURL: 'callbackURL',
|
||||
scope: scopes
|
||||
},
|
||||
function(accessToken, refreshToken, profile, cb) {
|
||||
User.findOrCreate({ icynetId: profile.id }, function(err, user) {
|
||||
return cb(err, user);
|
||||
});
|
||||
}));
|
||||
```
|
||||
|
||||
#### Authentication Requests
|
||||
Use `passport.authenticate()`, and specify the `'icynet'` strategy to authenticate requests.
|
||||
|
||||
For example, as a route middleware in an Express app:
|
||||
|
||||
```javascript
|
||||
app.get('/auth/icynet', passport.authenticate('icynet'));
|
||||
app.get('/auth/icynet/callback', passport.authenticate('icynet', {
|
||||
failureRedirect: '/'
|
||||
}), function(req, res) {
|
||||
res.redirect('/secretstuff') // Successful auth
|
||||
});
|
||||
```
|
||||
|
||||
#### Refresh Token Usage
|
||||
In some use cases where the profile may be fetched more than once or you want to keep the user authenticated, refresh tokens may wish to be used. A package such as `passport-oauth2-refresh` can assist in doing this.
|
||||
|
||||
Example:
|
||||
|
||||
`npm install passport-oauth2-refresh --save`
|
||||
|
||||
```javascript
|
||||
var IcyNetworkStrategy = require('passport-icynet').Strategy
|
||||
, refresh = require('passport-oauth2-refresh');
|
||||
|
||||
var icynetStrat = new Icy NetworkStrategy({
|
||||
clientID: 'id',
|
||||
clientSecret: 'secret',
|
||||
callbackURL: 'callbackURL'
|
||||
},
|
||||
function(accessToken, refreshToken, profile, cb) {
|
||||
profile.refreshToken = refreshToken; // store this for later refreshes
|
||||
User.findOrCreate({ icynetId: profile.id }, function(err, user) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
return cb(err, user);
|
||||
});
|
||||
});
|
||||
|
||||
passport.use(icynetStrat);
|
||||
refresh.use(icynetStrat);
|
||||
```
|
||||
|
||||
... then if we require refreshing when fetching an update or something ...
|
||||
|
||||
```javascript
|
||||
refresh.requestNewAccessToken('icynet', profile.refreshToken, function(err, accessToken, refreshToken) {
|
||||
if (err)
|
||||
throw; // boys, we have an error here.
|
||||
|
||||
profile.accessToken = accessToken; // store this new one for our new requests!
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Examples
|
||||
An Express server example can be found in the `/example` directory. Be sure to `npm install` in that directory to get the dependencies.
|
||||
|
||||
## Credits
|
||||
* Jared Hanson - used passport-github to understand passport more and kind of as a base.
|
17
example/package.json
Normal file
17
example/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "passport-icynet-example",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"author": "Evert \"Diamond\" Prants <evert@lunasqu.ee>",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.13.4",
|
||||
"express-session": "^1.13.0",
|
||||
"passport": "^0.3.2"
|
||||
}
|
||||
}
|
54
example/server.js
Normal file
54
example/server.js
Normal file
@ -0,0 +1,54 @@
|
||||
var express = require('express')
|
||||
, session = require('express-session')
|
||||
, passport = require('passport')
|
||||
, Strategy = require('../lib').Strategy
|
||||
, app = express();
|
||||
|
||||
passport.serializeUser(function(user, done) {
|
||||
done(null, user);
|
||||
});
|
||||
passport.deserializeUser(function(obj, done) {
|
||||
done(null, obj);
|
||||
});
|
||||
|
||||
var scopes = ['image', 'email'];
|
||||
|
||||
passport.use(new Strategy({
|
||||
clientID: '',
|
||||
clientSecret: '',
|
||||
callbackURL: 'http://localhost:5000/callback',
|
||||
scope: scopes
|
||||
}, function(accessToken, refreshToken, profile, done) {
|
||||
process.nextTick(function() {
|
||||
return done(null, profile);
|
||||
});
|
||||
}));
|
||||
|
||||
app.use(session({
|
||||
secret: 'keyboard cat',
|
||||
resave: false,
|
||||
saveUninitialized: false
|
||||
}));
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
app.get('/', passport.authenticate('icynet', { scope: scopes }), function(req, res) {});
|
||||
app.get('/callback',
|
||||
passport.authenticate('icynet', { failureRedirect: '/' }), function(req, res) { res.redirect('/info') } // auth success
|
||||
);
|
||||
app.get('/logout', function(req, res) {
|
||||
req.logout();
|
||||
res.redirect('/');
|
||||
});
|
||||
app.get('/info', checkAuth, function(req, res) {
|
||||
res.json(req.user);
|
||||
});
|
||||
|
||||
function checkAuth(req, res, next) {
|
||||
if (req.isAuthenticated()) return next();
|
||||
res.send('not logged in :(');
|
||||
}
|
||||
|
||||
app.listen(5000, function (err) {
|
||||
if (err) return console.log(err)
|
||||
console.log('Listening at http://localhost:5000/')
|
||||
})
|
14
lib/index.js
Normal file
14
lib/index.js
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
var Strategy = require('./strategy');
|
||||
|
||||
/**
|
||||
* Expose `Strategy` directly from package.
|
||||
*/
|
||||
exports = module.exports = Strategy;
|
||||
|
||||
/**
|
||||
* Export constructors.
|
||||
*/
|
||||
exports.Strategy = Strategy;
|
85
lib/strategy.js
Normal file
85
lib/strategy.js
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
var OAuth2Strategy = require('passport-oauth2')
|
||||
, InternalOAuthError = require('passport-oauth2').InternalOAuthError
|
||||
, util = require('util');
|
||||
|
||||
/**
|
||||
* `Strategy` constructor.
|
||||
*
|
||||
* The Icy Network authentication strategy authenticates requests by delegating
|
||||
* to Icy Network via the OAuth2.0 protocol
|
||||
*
|
||||
* Applications must supply a `verify` callback which accepts an `accessToken`,
|
||||
* `refreshToken` and service-specific `profile`, and then calls the `cb`
|
||||
* callback supplying a `user`, which should be set to `false` if the
|
||||
* credentials are not valid. If an exception occured, `err` should be set.
|
||||
*
|
||||
* Options:
|
||||
* - `clientID` OAuth ID to icynet
|
||||
* - `clientSecret` OAuth Secret to verify client to icynet
|
||||
* - `callbackURL` URL that icynet will redirect to after auth
|
||||
* - `scope` Array of permission scopes to request
|
||||
* Check the official documentation for valid scopes to pass as an array.
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} options
|
||||
* @param {function} verify
|
||||
* @access public
|
||||
*/
|
||||
function Strategy(options, verify) {
|
||||
options = options || {};
|
||||
options.authorizationURL = options.authorizationURL || 'https://icynet.eu/oauth2/authorize';
|
||||
options.tokenURL = options.tokenURL || 'https://icynet.eu/oauth2/token';
|
||||
options.scopeSeparator = options.scopeSeparator || ' ';
|
||||
|
||||
OAuth2Strategy.call(this, options, verify);
|
||||
this.name = 'icynet';
|
||||
this._oauth2.useAuthorizationHeaderforGET(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from `OAuth2Strategy`
|
||||
*/
|
||||
util.inherits(Strategy, OAuth2Strategy);
|
||||
|
||||
/**
|
||||
* Retrieve user profile from Icy Network.
|
||||
*
|
||||
* This function constructs a normalized profile.
|
||||
* Along with the properties returned from /oauth2/user, properties returned include:
|
||||
* - `email` Email address if you requested this scope
|
||||
* - `image` Profile picture if you requested this scope
|
||||
* - `privilege` Icy Network privilege level if you requested this scope
|
||||
* - `accessToken` The access token used to fetch the (may be useful for refresh)
|
||||
*
|
||||
* @param {string} accessToken
|
||||
* @param {function} done
|
||||
* @access protected
|
||||
*/
|
||||
Strategy.prototype.userProfile = function(accessToken, done) {
|
||||
var self = this;
|
||||
this._oauth2.get('https://icynet.eu/oauth2/user', accessToken, function(err, body, res) {
|
||||
if (err) {
|
||||
return done(new InternalOAuthError('Failed to fetch the user profile.', err))
|
||||
}
|
||||
|
||||
try {
|
||||
var parsedData = JSON.parse(body);
|
||||
} catch (e) {
|
||||
return done(new Error('Failed to parse the user profile.'));
|
||||
}
|
||||
|
||||
var profile = parsedData; // has the basic user stuff
|
||||
profile.provider = 'icynet';
|
||||
profile.accessToken = accessToken;
|
||||
|
||||
done(null, profile)
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose `Strategy`.
|
||||
*/
|
||||
module.exports = Strategy;
|
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "passport-icynet",
|
||||
"version": "0.0.1",
|
||||
"description": "Passport strategy for authentication with Icy Network (icynet.eu)",
|
||||
"main": "lib/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://gitlab.icynet.eu/IcyNetwork/passport-icynet.git"
|
||||
},
|
||||
"keywords": [
|
||||
"passport",
|
||||
"icynet",
|
||||
"auth",
|
||||
"authentication",
|
||||
"authn",
|
||||
"identity",
|
||||
"oauth2"
|
||||
],
|
||||
"author": "Evert \"Diamond\" Prants <evert@lunasqu.ee>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://gitlab.icynet.eu/IcyNetwork/passport-icynet/issues"
|
||||
},
|
||||
"homepage": "https://gitlab.icynet.eu/IcyNetwork/passport-icynet#readme",
|
||||
"dependencies": {
|
||||
"passport-oauth2": "^1.2.0"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user