├── handler.js ├── .babelrc ├── mocha.opts ├── .npmignore ├── .editorconfig ├── src ├── handler.js └── feathers-authentication-popups.js ├── .istanbul.yml ├── docs ├── client │ ├── auth-agent.off.md │ ├── auth-agent.on.md │ ├── auth-agent.once.md │ ├── auth-agent.emit.md │ ├── open-login-popup.md │ └── auth-agent.md ├── server │ └── express.md └── feathers-authentication-popups.md ├── .gitignore ├── .github ├── issue_template.md ├── stale.yml ├── pull_request_template.md └── contributing.md ├── .travis.yml ├── LICENSE ├── express.js ├── test └── index.test.js ├── package.json ├── CHANGELOG.md └── README.md /handler.js: -------------------------------------------------------------------------------- 1 | import handler from './lib/handler'; 2 | export default handler; 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ "add-module-exports" ], 3 | "presets": [ "es2015" ] 4 | } 5 | -------------------------------------------------------------------------------- /mocha.opts: -------------------------------------------------------------------------------- 1 | --recursive test/ 2 | --compilers js:babel-core/register 3 | --require jsdom-global/register -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .editorconfig 2 | .jshintrc 3 | .travis.yml 4 | .istanbul.yml 5 | .babelrc 6 | .idea/ 7 | src/ 8 | test/ 9 | !lib/ 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /src/handler.js: -------------------------------------------------------------------------------- 1 | import openLoginPopup from './feathers-authentication-popups'; 2 | 3 | // Allows simple registration as an event handler. ie. onClick={openLoginPopup(url)} 4 | export default function (url) { 5 | return function (event) { 6 | event.preventDefault(); 7 | return openLoginPopup(url); 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /.istanbul.yml: -------------------------------------------------------------------------------- 1 | verbose: false 2 | instrumentation: 3 | root: ./src/ 4 | excludes: 5 | - lib/ 6 | include-all-sources: true 7 | reporting: 8 | print: summary 9 | reports: 10 | - html 11 | - text 12 | - lcov 13 | watermarks: 14 | statements: [50, 80] 15 | lines: [50, 80] 16 | functions: [50, 80] 17 | branches: [50, 80] -------------------------------------------------------------------------------- /docs/client/auth-agent.off.md: -------------------------------------------------------------------------------- 1 | @function authentication-popups.authAgent.static.off off 2 | @parent authentication-popups.authAgent.static 3 | @signature `authAgent.off(eventName, handler)` 4 | 5 | Removes a handler function from the `authAgent` 6 | 1. **eventName** `{String}`: The name of the event to unsubscribe from. 7 | 2. **handler** `{Function}`: A reference to a previously-subscribed function to be unsubscribed. 8 | -------------------------------------------------------------------------------- /docs/client/auth-agent.on.md: -------------------------------------------------------------------------------- 1 | @function authentication-popups.authAgent.static.on on 2 | @parent authentication-popups.authAgent.static 3 | @signature `authAgent.on(eventName, handler)` 4 | 5 | Adds an event listener to the `authAgent` whose handler runs every time the event with given `eventName` is triggered. 6 | 1. **eventName** `{String}`: The name of the event to subscribe to. 7 | 2. **handler** `{Function}`: A function to be executed to handle the event. 8 | -------------------------------------------------------------------------------- /docs/client/auth-agent.once.md: -------------------------------------------------------------------------------- 1 | @function authentication-popups.authAgent.static.once once 2 | @parent authentication-popups.authAgent.static 3 | @signature `authAgent.once(eventName, handler)` 4 | 5 | Adds an event listener to the `authAgent` whose handler runs only once when the event with given `eventName` is triggered. 6 | 1. **eventName** `{String}`: The name of the event to subscribe to. 7 | 2. **handler** `{Function}`: A function to be executed to handle the event. 8 | -------------------------------------------------------------------------------- /docs/client/auth-agent.emit.md: -------------------------------------------------------------------------------- 1 | @function authentication-popups.authAgent.static.emit emit 2 | @parent authentication-popups.authAgent.static 3 | @signature `authAgent.emit(eventName, args)` 4 | 5 | Triggers the event attached to the provided `eventName` and calls the subscribed handlers with the `args`. 6 | 1. **eventName** `{String}`: The name of the event to trigger. 7 | 2. **args** `{any}`: arguments to be passed to event handlers, usually authentication-related information (like a JSON Web Token). 8 | -------------------------------------------------------------------------------- /docs/client/open-login-popup.md: -------------------------------------------------------------------------------- 1 | @function authentication-popups.openLoginPopup openLoginPopup 2 | @parent authentication-popups.client 3 | @description Open a centered popup window. 4 | 5 | @signature `openLoginPopup(url, options)` 6 | 7 | Open a centered popup window at the provided `url`. 8 | 9 | ```js 10 | import openLoginPopup from 'authentication-popups'; 11 | 12 | openLoginPopup('/auth/github'); 13 | ``` 14 | 15 | @param {String} url The URL for the new window. 16 | @param {Object} options Allows changing the `width` and `height` of the popup window. 17 | @option [width=1024] The popup window width in pixels. 18 | @option [height=630] The popup window height in pixels. 19 | 20 | @body -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # Compiled binary addons (http://nodejs.org/api/addons.html) 22 | build/Release 23 | 24 | # Dependency directory 25 | # Commenting this out is preferred by some people, see 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 27 | node_modules 28 | 29 | # Users Environment Variables 30 | .lock-wscript 31 | 32 | # The compiled/babelified modules 33 | lib/ -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Steps to reproduce 2 | 3 | (First please check that this issue is not already solved as [described 4 | here](https://github.com/feathersjs/feathers/blob/master/.github/contributing.md#report-a-bug)) 5 | 6 | - [ ] Tell us what broke. The more detailed the better. 7 | - [ ] If you can, please create a simple example that reproduces the issue and link to a gist, jsbin, repo, etc. 8 | 9 | ### Expected behavior 10 | Tell us what should happen 11 | 12 | ### Actual behavior 13 | Tell us what happens instead 14 | 15 | ### System configuration 16 | 17 | Tell us about the applicable parts of your setup. 18 | 19 | **Module versions** (especially the part that's not working): 20 | 21 | **NodeJS version**: 22 | 23 | **Operating System**: 24 | 25 | **Browser Version**: 26 | 27 | **React Native Version**: 28 | 29 | **Module Loader**: -------------------------------------------------------------------------------- /docs/server/express.md: -------------------------------------------------------------------------------- 1 | @function {ExpressMiddleware} authentication-popups.express ./express 2 | @parent authentication-popups.server 3 | @description Express middleware for handling successful OAuth logins. 4 | 5 | @signature `successHandler(options|cookieName)` 6 | 7 | Creates Express middleware that handles successful auth by returning an HTML page that: 8 | * Pulls the data from a provided `cookieName`. 9 | * Sends the data to the parent window through the `authAgent`. 10 | * Closes the popup window. 11 | 12 | ```js 13 | const successHandler = require('authentication-popups/express'); 14 | 15 | app.get('/auth/success', successHandler('feathers-jwt')); 16 | // or pull from your app config variables. 17 | app.get('/auth/success', successHandler( app.get('cookie') )); 18 | ``` 19 | 20 | @param {Object} options An object with a `name` property containingthe cookie name. 21 | @option {String} name The cookie name. 22 | @param {String} cookieName The name of the cookie location. 23 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 84 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - greenkeeper 8 | - bug 9 | - security 10 | - enhancement 11 | # Label to use when marking an issue as stale 12 | staleLabel: wontfix 13 | # Comment to post when marking an issue as stale. Set to `false` to disable 14 | markComment: > 15 | This issue has been automatically marked as stale because it has not had 16 | recent activity. It will be closed if no further activity occurs. 17 | Apologies if the issue could not be resolved successfully. FeathersJS ecosystem 18 | modules are community maintained so there may be a chance that there isn't anybody 19 | available to help at the moment (see other ways to get help [here](https://docs.feathersjs.com/help/readme.html)). 20 | # Comment to post when closing a stale issue. Set to `false` to disable 21 | closeComment: false 22 | -------------------------------------------------------------------------------- /src/feathers-authentication-popups.js: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'events'; 2 | 3 | window.authAgent = new EventEmitter(); 4 | 5 | export const authAgent = window.authAgent; 6 | 7 | /* 8 | * A helper function that opens the provided URL in a centered popup. 9 | * Accepts an `options` object with `width` and `height` number properties. 10 | */ 11 | export default function openLoginPopup (url, options = {}) { 12 | let width = options.width || 1024; 13 | let height = options.height || 640; 14 | let {top, left} = getCenterCoordinates(window, width, height); 15 | let params = `width=${width}, height=${height}, top=${top}, left=${left}`; 16 | return window.open(url, 'authWindow', params); 17 | } 18 | 19 | /* 20 | * Returns the coordinates to center a popup window in the viewport with 21 | * the provided width and height args. 22 | */ 23 | export function getCenterCoordinates (window, width, height) { 24 | return { 25 | left: window.screenX + ((window.outerWidth - width) / 2), 26 | top: window.screenY + ((window.outerHeight - height) / 2) 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 'node' 4 | - '6' 5 | - '4' 6 | addons: 7 | code_climate: 8 | repo_token: ae81a2d00d699b14a7f8bef71adb8f145c7f3f71d41f648a2f3637e981f0a14c 9 | notifications: 10 | email: false 11 | slack: 12 | rooms: 13 | secure: DY9seyYvvSgJDT3FJZvojZr8qhve6a0QKfxYGVbtM+alrtEid62MDaBlbkkr2I2ryQ8+MoYZNQ4Uyp1GPgR02CHx8xZTMdpr6GL2mq+g1IgFAR8z7hlgF7GD6zl7cIp3OPKo3sd/ie/O6G4HvRoCnvgHC0rQu2L2/zPDsZeuFBVyvQohgs1ecvTb5yPC13+44+T6hXUpgzAvvJQXnpYPX3nlZYkpcU3lYDJBpz0/6cqSRO9bFT4ueiae9d39MzsLnsTnmctYAGeXFNn8ZmUQdPfWzphnfVVfyFyCHEuMNZOT6oyKHFLM8dD8Zw4CE4wp7z94dZBwVHN/lpBYEpitSpZmDPbAIjXu4vMDAzFNLd4J4tGN4dUj95c0AqF2JcIJriHfjLCUSyFNLXt2JgiaPq6TXXGkBc8+lOxio/3IjsEaDBhLplPjW/0BHqb3NrUh90AxKWmo+aGx+opX6/Ex920H8IRcwzdITiUWbfhdY2pDP7GQ4TgJhiZVoSp/D1jXrT2ujDE+NUv5H4RRCj/33GlLUirqI/MHJRqSceihEhbNcp5/Ro5AHT7I95jugQq5C25nJisAhOgrXgLeiBrT+tgA2BjTJQxCACa3ohOKXrZC0DYlkN6NPYwuEp2reRueLaoaQ+wzKcwnOuKrv1euniP7oOGlV1bIjuoTMHZrPUw= 14 | before_script: 15 | - npm install -g codeclimate-test-reporter 16 | after_script: 17 | - codeclimate-test-reporter < coverage/lcov.info 18 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Summary 2 | 3 | (If you have not already please refer to the contributing guideline as [described 4 | here](https://github.com/feathersjs/feathers/blob/master/.github/contributing.md#pull-requests)) 5 | 6 | - [ ] Tell us about the problem your pull request is solving. 7 | - [ ] Are there any open issues that are related to this? 8 | - [ ] Is this PR dependent on PRs in other repos? 9 | 10 | If so, please mention them to keep the conversations linked together. 11 | 12 | ### Other Information 13 | 14 | If there's anything else that's important and relevant to your pull 15 | request, mention that information here. This could include 16 | benchmarks, or other information. 17 | 18 | Your PR will be reviewed by a core team member and they will work with you to get your changes merged in a timely manner. If merged your PR will automatically be added to the changelog in the next release. 19 | 20 | If your changes involve documentation updates please mention that and link the appropriate PR in [feathers-docs](https://github.com/feathersjs/feathers-docs). 21 | 22 | Thanks for contributing to Feathers! :heart: -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Feathers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /express.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function (options) { 3 | var cookieName = typeof options === 'string' ? options : options.name; 4 | if (!cookieName) { 5 | throw new Error('You must provide a cookie name {String} or an object with a `name` property to the feathers-authentication-popups middleware.'); 6 | } 7 | var template = ` 8 | 9 | 30 | 31 | 32 | `; 33 | 34 | return function (req, res) { 35 | res.send(template); 36 | }; 37 | }; 38 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import openLoginPopup, {authAgent, getCenterCoordinates} from '../src/feathers-authentication-popups'; 3 | import clickHandler from '../src/handler'; 4 | import EventEmitter from 'events'; 5 | 6 | var oldWindow = global.window; 7 | global.window = { 8 | open () { 9 | return {success: true}; 10 | } 11 | }; 12 | 13 | describe('Client Utils', () => { 14 | describe('OAuth Popup', () => { 15 | it(`opens new window`, () => { 16 | let authWindow = openLoginPopup('/auth/github'); 17 | expect(authWindow).to.not.equal(undefined); 18 | }); 19 | }); 20 | 21 | describe('Closure / Click Handler Version', () => { 22 | it(`returns a function`, () => { 23 | expect(typeof clickHandler).to.equal('function'); 24 | expect(typeof clickHandler('/auth/github')).to.equal('function'); 25 | }); 26 | 27 | it(`opens new window`, () => { 28 | let event = { 29 | preventDefault () {} 30 | }; 31 | let authWindow = clickHandler('/auth/github')(event); 32 | expect(authWindow).to.not.equal(undefined); 33 | global.window = oldWindow; 34 | }); 35 | }); 36 | 37 | describe('authAgent EventEmitter', () => { 38 | it(`sets up an eventEmitter at window.authAgent`, () => { 39 | expect(authAgent instanceof EventEmitter).to.equal(true); 40 | }); 41 | }); 42 | 43 | describe('getCenterCoordinates', () => { 44 | it(`function exists`, () => { 45 | expect(typeof getCenterCoordinates).to.equal('function'); 46 | }); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /docs/client/auth-agent.md: -------------------------------------------------------------------------------- 1 | @module {EventEmitter} window.authAgent 2 | @parent authentication-popups.client 3 | @group authentication-popups.authAgent.static static 4 | @description Enable observable messages from other windows. 5 | 6 | @type {EventEmitter} 7 | 8 | `window.authAgent` is an [EventEmitter](https://nodejs.org/api/events.html) that allows popup windows to send information back to the main window. It has four useful methods: 9 | 10 | - [authentication-popups.authAgent.static.on] registers a function to run when an event is emitted. 11 | - [authentication-popups.authAgent.static.once] is like [authentication-popups.authAgent.static.on], but only runs the function once. 12 | - [authentication-popups.authAgent.static.off] deregisters a function from an event. 13 | - [authentication-popups.authAgent.static.emit] triggers an event, which runs all of its registered functions. 14 | 15 | @body 16 | 17 | ## Use in the primary application window 18 | 19 | ```js 20 | // Adds 21 | import 'authentication-popups'; 22 | 23 | function doSomethingWithToken (token) { 24 | // Do something with the token 25 | } 26 | 27 | window.authAgent.on('login', doSomethingWithToken); 28 | ``` 29 | The `doSomethingWithToken` function will run when the 'login' event is emitted on `window.authAgent`. The next section shows how to use it from a popup window. 30 | 31 | ## Use in the popup window 32 | Due to browser security features, both windows must be on the same domain. 33 | 34 | ```js 35 | var cookieContents = readCookie('feathers-jwt'); 36 | 37 | // Trigger the 'login' event on the primary window's `authAgent` 38 | window.opener.authAgent.emit('login', cookieContents); 39 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feathers-authentication-popups", 3 | "description": "Server and client utils for implementing popup-based authentication flows", 4 | "version": "0.1.2", 5 | "homepage": "https://github.com/feathersjs/feathers-authentication-popups", 6 | "main": "lib/feathers-authentication-popups", 7 | "keywords": [ 8 | "feathers", 9 | "feathers-plugin" 10 | ], 11 | "license": "MIT", 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/feathersjs/feathers-authentication-popups.git" 15 | }, 16 | "author": { 17 | "name": "Marshall Thompson", 18 | "email": "marshall@creativeideall.net", 19 | "url": "https://feathersjs.com" 20 | }, 21 | "contributors": [], 22 | "bugs": { 23 | "url": "https://github.com/feathersjs/feathers-authentication-popups/issues" 24 | }, 25 | "engines": { 26 | "node": ">= 4.6.0" 27 | }, 28 | "scripts": { 29 | "prepublish": "npm run compile", 30 | "publish": "git push origin --tags && npm run changelog && git push origin", 31 | "release:patch": "npm version patch && npm publish", 32 | "release:minor": "npm version minor && npm publish", 33 | "release:major": "npm version major && npm publish", 34 | "changelog": "github_changelog_generator && git add CHANGELOG.md && git commit -am \"Updating changelog\"", 35 | "compile": "rimraf lib/ && babel -d lib/ src/", 36 | "watch": "babel --watch -d lib/ src/", 37 | "lint": "semistandard src/**/*.js test/**/*.js --fix", 38 | "mocha": "mocha --opts mocha.opts", 39 | "coverage": "istanbul cover _mocha -- --opts mocha.opts", 40 | "test": "npm run compile && npm run lint && npm run coverage", 41 | "start": "npm run compile && node example/app" 42 | }, 43 | "semistandard": { 44 | "sourceType": "module", 45 | "env": [ 46 | "mocha" 47 | ] 48 | }, 49 | "directories": { 50 | "lib": "lib" 51 | }, 52 | "dependencies": { 53 | "debug": "^3.0.1", 54 | "events": "^1.1.1", 55 | "feathers-errors": "^2.4.0" 56 | }, 57 | "devDependencies": { 58 | "babel-cli": "^6.18.0", 59 | "babel-core": "^6.18.0", 60 | "babel-plugin-add-module-exports": "^0.2.1", 61 | "babel-preset-es2015": "^6.18.0", 62 | "chai": "^4.0.0", 63 | "istanbul": "^1.1.0-alpha.1", 64 | "jsdom": "11.3.0", 65 | "jsdom-global": "3.0.2", 66 | "mocha": "^4.0.0", 67 | "rimraf": "^2.5.4", 68 | "semistandard": "^11.0.0" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [v0.1.2](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.1.2) (2016-11-22) 4 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.1.1...v0.1.2) 5 | 6 | ## [v0.1.1](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.1.1) (2016-11-22) 7 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.1.0...v0.1.1) 8 | 9 | ## [v0.1.0](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.1.0) (2016-11-22) 10 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.9...v0.1.0) 11 | 12 | **Merged pull requests:** 13 | 14 | - Add a closure version for simple use in JSX. [\#1](https://github.com/feathersjs/feathers-authentication-popups/pull/1) ([marshallswain](https://github.com/marshallswain)) 15 | 16 | ## [v0.0.9](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.9) (2016-11-09) 17 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.8...v0.0.9) 18 | 19 | ## [v0.0.8](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.8) (2016-11-01) 20 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.7...v0.0.8) 21 | 22 | ## [v0.0.7](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.7) (2016-11-01) 23 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.6...v0.0.7) 24 | 25 | ## [v0.0.6](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.6) (2016-10-29) 26 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.5...v0.0.6) 27 | 28 | ## [v0.0.5](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.5) (2016-10-27) 29 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.4...v0.0.5) 30 | 31 | ## [v0.0.4](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.4) (2016-10-27) 32 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.3...v0.0.4) 33 | 34 | ## [v0.0.3](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.3) (2016-10-27) 35 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.2...v0.0.3) 36 | 37 | ## [v0.0.2](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.2) (2016-10-27) 38 | [Full Changelog](https://github.com/feathersjs/feathers-authentication-popups/compare/v0.0.1...v0.0.2) 39 | 40 | ## [v0.0.1](https://github.com/feathersjs/feathers-authentication-popups/tree/v0.0.1) (2016-10-27) 41 | 42 | 43 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* -------------------------------------------------------------------------------- /docs/feathers-authentication-popups.md: -------------------------------------------------------------------------------- 1 | @module authentication-popups 2 | @description Implement popup-based authentication flows with server and client utilities. 3 | @parent can-ecosystem 4 | @group authentication-popups.client 0 client 5 | @group authentication-popups.server 1 server 6 | @package ../package.json 7 | 8 | @body 9 | 10 | ## Use 11 | 12 | When implementing an OAuth login workflow with the bundled utilities, the general steps are as follows: 13 | 14 | 1. The `[authentication-popups.openLoginPopup]` function is used (eg. attached to a user action like a button click) to open a popup window with the OAuth provider's authorization form (eg. Facebook's login window). This also sets up the [authentication-popups.authAgent] object used in the next step. Here's an example of importing and using the `[authentication-popups.openLoginPopup]` function in a component. 15 | ```js 16 | var Component = require('can-component'); 17 | var DefineMap = require('can-define/map/'); 18 | var openLoginPopup = require('authentication-popups'); 19 | 20 | var ViewModel = DefineMap.extend({ 21 | openLoginPopup, 22 | }); 23 | 24 | Component.extend({ 25 | tag: 'github-login-button', 26 | ViewModel, 27 | template 28 | }); 29 | ``` 30 | 31 | ```hbs 32 | 33 | ``` 34 | 35 | 2. A handler function is setup on the [authentication-popups.authAgent]'s `login` event using the [authentication-popups.authAgent.static.on] or [authentication-popups.authAgent.static.once] method. This awaits receipt of login-related data from the popup window. 36 | 37 | ```js 38 | require('feathers-authentication-popups'); 39 | 40 | window.authAgent.on('login', function (authData) { 41 | // handle the authData 42 | }); 43 | ``` 44 | 45 | 3. The user authorizes the action on the OAuth provider's page. 46 | 4. The OAuth provider redirects the popup window back to a URL that has been preregistered as a "success redirect" URL. 47 | 5. A server "middleware" function creates a cookie containing authorization data. This middleware is not bundled with `authentication-popups`, but would be come with an authentication module such as [PassportJS](http://passportjs.org/) or the [feathers-authentication](https://github.com/feathersjs/feathers-authentication) plugin for [FeathersJS](http://feathersjs.com). 48 | 6. The included [authentication-popups.express] middleware sends the cookie and some basic HTML to the popup window. Here's a simplified example of using the middleware in an Express server: 49 | 50 | ```js 51 | var express = require('express'); 52 | var successHandler = require('authentication-popups/express'); 53 | var app = express(); 54 | 55 | // Your PassportJS or other authentication middleware would go here. 56 | 57 | app.use('/auth/success', successHandler('cookie-name')); 58 | ``` 59 | 60 | 7. The script sent by the [authentication-popups.express] middleware then 61 | - pulls the data from the cookie 62 | - [authentication-popups.authAgent.static.emit]s the data on the `login` event to the main window's [authentication-popups.authAgent authAgent]. 63 | - closes the popup window. 64 | 8. The event handler created in step 2, above, receives the raw data from the cookie, allowing the application to respond as needed. 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # feathers-authentication-popups 2 | 3 | > __Unmaintained:__ This project is no longer maintained 4 | 5 | [![Greenkeeper badge](https://badges.greenkeeper.io/feathersjs/feathers-authentication-popups.svg)](https://greenkeeper.io/) 6 | 7 | [![Build Status](https://travis-ci.org/feathersjs/feathers-authentication-popups.png?branch=master)](https://travis-ci.org/feathersjs/feathers-authentication-popups) 8 | [![Code Climate](https://codeclimate.com/github/feathersjs/feathers-authentication-popups/badges/gpa.svg)](https://codeclimate.com/github/feathersjs/feathers-authentication-popups) 9 | [![Test Coverage](https://codeclimate.com/github/feathersjs/feathers-authentication-popups/badges/coverage.svg)](https://codeclimate.com/github/feathersjs/feathers-authentication-popups/coverage) 10 | [![Dependency Status](https://img.shields.io/david/feathersjs/feathers-authentication-popups.svg?style=flat-square)](https://david-dm.org/feathersjs/feathers-authentication-popups) 11 | [![Download Status](https://img.shields.io/npm/dm/feathers-authentication-popups.svg?style=flat-square)](https://www.npmjs.com/package/feathers-authentication-popups) 12 | [![Slack Status](http://slack.feathersjs.com/badge.svg)](http://slack.feathersjs.com) 13 | 14 | > Server and client utils for implementing popup-based authentication flows 15 | 16 | ## Summary 17 | 18 | This package includes a few useful tools for implementing popup-based OAuth login flows. It contains utility functions for the browser and middleware for the server. 19 | 20 | ## Using the Client Utils 21 | There are two client utilities: one to assist with opening popups, and another to assist in cross-window communication. 22 | 23 | ## `openLoginPopup(url, options)` 24 | Opens a centered popup window at the given `url`. 25 | 26 | ```js 27 | import openLoginPopup from 'feathers-authentication-popups'; 28 | 29 | openLoginPopup('/auth/github'); 30 | ``` 31 | 32 | 1. **url** `{String}`: The URL of the new window. 33 | 2. **options** `{Object}`: optional - allows for customizing the `width` and `height` of the popup window. 34 | 35 | The default `options` are: 36 | * `width`: 1024, 37 | * `height`: 630 38 | 39 | ## `authAgent` 40 | 41 | An EventEmitter automatically assigned as a global at `window.authAgent` to allow popup windows to send information back to the main window. Both windows must be on the same domain for this to work. 42 | 43 | **Usage in the primary application window:** 44 | 45 | ```js 46 | // Adds 47 | import 'feathers-authentication-popups'; 48 | 49 | function doSomethingWithToken (token) { 50 | // Do something with the token 51 | } 52 | 53 | window.authAgent.on('login', doSomethingWithToken); 54 | ``` 55 | The `doSomethingWithToken` function will run when the 'login' event is emitted on `window.authAgent`. 56 | 57 | **Usage in the popup window on the same domain:** 58 | ```js 59 | var token = readCookie('feathers-jwt'); 60 | 61 | // Trigger the 'login' event on the main window's `authAgent` 62 | window.opener.authAgent.emit('login', token); 63 | ``` 64 | 65 | ### `authAgent.on(eventName, handler)` 66 | 67 | Adds an event listener to the `authAgent` whose handler runs every time the event with given `eventName` is triggered. 68 | 1. **eventName** `{String}`: The name of the event to subscribe to. 69 | 2. **handler** `{Function}`: A function to be executed to handle the event. 70 | 71 | ### `authAgent.once(eventName, handler)` 72 | 73 | Adds an event listener to the `authAgent` whose handler runs only once when the event with given `eventName` is triggered. 74 | 1. **eventName** `{String}`: The name of the event to subscribe to. 75 | 2. **handler** `{Function}`: A function to be executed to handle the event. 76 | 77 | ### `authAgent.off(eventName, handler)` 78 | 79 | Removes a handler function from the `authAgent` 80 | 1. **eventName** `{String}`: The name of the event to unsubscribe from. 81 | 2. **handler** `{Function}`: A reference to a previously-subscribed function to be unsubscribed. 82 | 83 | ### `authAgent.emit(eventName, args)` 84 | 85 | Triggers the event attached to the provided `eventName` and calls the subscribed handlers with the `args`. 86 | 1. **eventName** `{String}`: The name of the event to trigger. 87 | 2. **args** `{any}`: arguments to be passed to event handlers, usually authentication-related information (like a JSON Web Token). 88 | 89 | ## Using the Express Middleware 90 | 91 | The Express middleware is meant to be registered as the success callback of a Feathers authentication workflow. 92 | 93 | ### `successHandler(options|cookieName)` 94 | 95 | Creates Express middleware that handles successful auth by returning an HTML page that: 96 | * Pulls the token from the cookie location. 97 | * Sends the token to the parent window through the `authAgent`. 98 | * Closes the popup window. 99 | 100 | ```js 101 | var successHandler = require('feathers-authentication-popups/express'); 102 | 103 | // Pass an object containing a `name` attribute. 104 | var options = app.get('cookie'); 105 | app.get('/auth/success', successHandler(options)); 106 | 107 | // Or pass a string for the cookie name. 108 | app.get('/auth/success', successHandler('feathers-jwt')); 109 | ``` 110 | 111 | 1. **options** `{Object}`: An object with a `name` attribute. 112 | 1. **cookieName** `{String}`: The cookie name. 113 | 114 | ## License 115 | 116 | Copyright (c) 2016 117 | 118 | Licensed under the [MIT license](LICENSE). 119 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Feathers 2 | 3 | Thank you for contributing to Feathers! :heart: :tada: 4 | 5 | This repo is the main core and where most issues are reported. Feathers embraces modularity and is broken up across many repos. To make this easier to manage we currently use [Zenhub](https://www.zenhub.com/) for issue triage and visibility. They have a free browser plugin you can install so that you can see what is in flight at any time, but of course you also always see current issues in Github. 6 | 7 | ## Report a bug 8 | 9 | Before creating an issue please make sure you have checked out the docs, specifically the [FAQ](https://docs.feathersjs.com/help/faq.html) section. You might want to also try searching Github. It's pretty likely someone has already asked a similar question. 10 | 11 | If you haven't found your answer please feel free to join our [slack channel](http://slack.feathersjs.com), create an issue on Github, or post on [Stackoverflow](http://stackoverflow.com) using the `feathers` or `feathersjs` tag. We try our best to monitor Stackoverflow but you're likely to get more immediate responses in Slack and Github. 12 | 13 | Issues can be reported in the [issue tracker](https://github.com/feathersjs/feathers/issues). Since feathers combines many modules it can be hard for us to assess the root cause without knowing which modules are being used and what your configuration looks like, so **it helps us immensely if you can link to a simple example that reproduces your issue**. 14 | 15 | ## Report a Security Concern 16 | 17 | We take security very seriously at Feathers. We welcome any peer review of our 100% open source code to ensure nobody's Feathers app is ever compromised or hacked. As a web application developer you are responsible for any security breaches. We do our very best to make sure Feathers is as secure as possible by default. 18 | 19 | In order to give the community time to respond and upgrade we strongly urge you report all security issues to us. Send one of the core team members a PM in [Slack](http://slack.feathersjs.com) or email us at hello@feathersjs.com with details and we will respond ASAP. 20 | 21 | For full details refer to our [Security docs](https://docs.feathersjs.com/SECURITY.html). 22 | 23 | ## Pull Requests 24 | 25 | We :heart: pull requests and we're continually working to make it as easy as possible for people to contribute, including a [Plugin Generator](https://github.com/feathersjs/generator-feathers-plugin) and a [common test suite](https://github.com/feathersjs/feathers-service-tests) for database adapters. 26 | 27 | We prefer small pull requests with minimal code changes. The smaller they are the easier they are to review and merge. A core team member will pick up your PR and review it as soon as they can. They may ask for changes or reject your pull request. This is not a reflection of you as an engineer or a person. Please accept feedback graciously as we will also try to be sensitive when providing it. 28 | 29 | Although we generally accept many PRs they can be rejected for many reasons. We will be as transparent as possible but it may simply be that you do not have the same context or information regarding the roadmap that the core team members have. We value the time you take to put together any contributions so we pledge to always be respectful of that time and will try to be as open as possible so that you don't waste it. :smile: 30 | 31 | **All PRs (except documentation) should be accompanied with tests and pass the linting rules.** 32 | 33 | ### Code style 34 | 35 | Before running the tests from the `test/` folder `npm test` will run ESlint. You can check your code changes individually by running `npm run lint`. 36 | 37 | ### ES6 compilation 38 | 39 | Feathers uses [Babel](https://babeljs.io/) to leverage the latest developments of the JavaScript language. All code and samples are currently written in ES2015. To transpile the code in this repository run 40 | 41 | > npm run compile 42 | 43 | __Note:__ `npm test` will run the compilation automatically before the tests. 44 | 45 | ### Tests 46 | 47 | [Mocha](http://mochajs.org/) tests are located in the `test/` folder and can be run using the `npm run mocha` or `npm test` (with ESLint and code coverage) command. 48 | 49 | ### Documentation 50 | 51 | Feathers documentation is contained in Markdown files in the [feathers-docs](https://github.com/feathersjs/feathers-docs) repository. To change the documentation submit a pull request to that repo, referencing any other PR if applicable, and the docs will be updated with the next release. 52 | 53 | ## External Modules 54 | 55 | If you're written something awesome for Feathers, the Feathers ecosystem, or using Feathers please add it to the [showcase](https://docs.feathersjs.com/why/showcase.html). You also might want to check out the [Plugin Generator](https://github.com/feathersjs/generator-feathers-plugin) that can be used to scaffold plugins to be Feathers compliant from the start. 56 | 57 | If you think it would be a good core module then please contact one of the Feathers core team members in [Slack](http://slack.feathersjs.com) and we can discuss whether it belongs in core and how to get it there. :beers: 58 | 59 | ## Contributor Code of Conduct 60 | 61 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 62 | 63 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 64 | 65 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. 66 | 67 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. 68 | 69 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 70 | 71 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) 72 | --------------------------------------------------------------------------------