Natural Preference for Minification

    @rcarls/passport-indieauth

    2.0.1 • Public • Published

    #passport-indieauth Build Status Coverage Status Code Climate

    An IndieAuth authentication strategy for Passport.

    This module exports a Passport Strategy class to be used by applications that utilize Passport middleware for authentication. By plugging into Passport, developers can easily integrate IndieAuth into any Node.js application or framework that supports Connect-style middleware, including the popular Express.

    This strategy only implements the client-side of the IndieAuth protocol, and relies on endpoint discovery to determine how to delegate authentication. A fallback authorization endpoint can be configured, and the strategy defaults to using the canonical indieauth.com.

    Breaking changes from v1.x

    The verify callback now supplies an access token instead of the requested scope as the second argument. It is given that the requesting app will already know which scope(s) it is requesting, and four arguments to a callback is already one too many.

    Install

    $ npm install @rcarls/passport-indieauth

    Usage

    Configure Strategy

    The IndieAuth authentication strategy only requires a client id, the domain of the web application, and a redirect URI for authorization flow. The request object can optionally be passed to the verify callback.

    require('passport');
    require('@rcarls/passport-indieauth');
    
    // ...
    
    passport.use(new IndieAuthStrategy({
    	clientId: 'https://example-client.com/',
    	redirectUri: 'https://example-client.com/auth',
    	passReqToCallback: true,
      }, function(req, uid, token, profile, done) {
      	// The verify callback:
      	// Verify the returned user credentials are valid
    	  User.findOne({ uid: uid }, function(err, user) {
    		  // and return the existing or newly created user
    		  return done(err, user);
    	  });
      });
    });

    Configuration Options

    • clientId {String} - The application's client id. Must be a valid URL that accepts HTTP or HTTPS requests. The convention is to include a trailing slash after the domain name, but is not required. (ex: https://example-client.com/)
    • redirectUri {String} - The authorization redirect URI.
    • responseType {String} - The response type of the auth request. Valid values are 'id' (identification only), or 'code' (identification + authorization) (optional, defaults to 'id')
    • defaultAuthEndpoint {String} - The fallback authorization service to use if not discovered. (optional, defaults to 'https://indieauth.com/auth')
    • scopeDelimiter {String} - Delimiter for separating scopes in the request. Defaults to a space.
    • passReqToCallback {Boolean} - If true, passes the request object to the verify callback. (optional, defaults to false)

    Authenticate Requests

    Use passport.authenticate(), specifying the 'indieauth' strategy, to authenticate requests. The strategy can handle both POST and GET requests.

    // example authenticating a request to a route in Express
    
    app.get('/profile', passport.authenticate('indieauth', { failureRedirect: '/login' }),
      function(req, res) {
    	  // req.user contains the authenticated user instance
    	  return res.send('<h1>Logged in as ' + req.user.url + '</h1>');
      });

    You can use the strategy for both requesting an auth code from a login page, and handling the code verification on the redirect route.

    // Capture the request params on POST and kick off the authorization flow
    app.post('/auth', passport.authenticate('indieauth', {
    	failureRedirect: '/login', failureFlash: true,
    }));
    
    // put on your redirect route to handle the auth response and verification
    app.get('/auth/callback', passport.authenticate('indieauth', {
    	successRedirect: '/profile', failureRedirect: '/login', failureFlash: true,
    }));

    Getting the User Profile

    The strategy provides structured profile data consistent with the Portable Contacts draft spec if found when parsing the user's domain response. Note that not all possible mappings are currently implemented at this time. The full parsed JSON data is included in the _json property. See microformats2 for the structure of this data, and h-card draft spec for standard properties.

    passport.use(new IndieAuthStrategy({
    	clientId: 'https://example-client.com/',
    	redirectUri: 'https://example-client.com/auth/callback',
      }, function(uid, token, profile, done) {
        // Save access token for micropub or media endpoint requests
        var user = {
    		uid: uid,
    		token: token,
    	};
    	
    	if (profile.name && profile.name.formatted) {
    		user.name = profile.name.formatted;
    	}
    	
    	if (profile.photos && profile.photos.length) {
    		user.avatarUrl = profile.photos[0].value;
    	}
    	
    	// etc.
      });
    });

    Using IndieAuth

    See the IndieWebCamp wiki entry for IndieAuth and setup instructions to start using your own domain for web sign-in. In addition to your client id being your web application's domain name, the protocol requires the inclusion of a <link rel="redirect_uri" /> tag on your root page. (note: this is seems to be a "soft" requirement at this point).

    Users may optionally specify a rel="authorization_endpoint" on thier home page to use an authentication service of thier choosing. To make profile information available, a user will need to have an h-card in the body of thier home page.

    Users may also optionally specify a rel="token_endpoint" on thier home page to indicate the availability of generating access token on thier behalf. In order for a token to be acquired, and authorization_endpoint also needs to be configured or discoverable by the token_endpoint.

    Other Usage Notes

    • The strategy currently uses a _csrf request property as the state parameter in authentication requests to the discovered service to prevent CSRF attacks. It is recommended to use a middleware like csurf to generate csrf tokens to embed on your login page.

    • For allowing unauthenticated requests, specify passport-anonymous after indieauth:

      passport.authenticate(['indieauth', 'anonymous']);
    • Even though this stategy obtains an access token when possible, it does not authenticate access tokens. Use another passport strategy like passport-http-bearer.

    Related Modules

    • passport-indieauth - IndieAuth authentication strategy for Passport.
    • relmeauth - A rel=me auth middleware implementation in node.js. Works with any connect-type web application.
    • passport - Simple, unobtrusive authentication for Node.js.
    • microformat-node - Microformats parser for node.js.

    Tests

    $ npm install
    $ npm test

    Contributing

    Please feel free to submit bugs and feature requests through the issues interface. I welcome pull requests, even for small things.

    Tests

    The test suite is located in the test/ directory. All new features are expected to have corresponding test cases. Ensure that all tests are passing by running the test command. Improvements to the test suite are welcome (I'm new), submit a pull request!

    npm test

    Credits

    License

    The MIT License

    Copyright (c) 2016 Richard Carls

    Install

    npm i @rcarls/passport-indieauth

    DownloadsWeekly Downloads

    1

    Version

    2.0.1

    License

    MIT

    Last publish

    Collaborators

    • rcarls