Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dimapaloskin committed Apr 14, 2017
0 parents commit 5d823d5
Show file tree
Hide file tree
Showing 7 changed files with 2,481 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
language: node_js
node_js:
- 7
cache:
directories:
- $HOME/.npm
- node_modules
before_script:
npm install micro
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# microauth-slack

> slack oauth for [micro](https://github.com/zeit/micro/)
[![Build Status](https://travis-ci.org/microauth/microauth-slack.svg?branch=master)](https://travis-ci.org/microauth/microauth-slack)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)

Add [slack](https://slack.com) authentication to your [micro](https://github.com/zeit/micro/) service as easy as a flick of your fingers.
This module is a part of [microauth](https://github.com/microauth/microauth) collection.

## Installation

```sh
npm install --save microauth-slack
# or
yarn add microauth-slack
```

## Usage

app.js
```js
const { send } = require('micro');
const microAuthSlack = require('./index');

const options = {
clientId: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET',
callbackUrl: 'http://localhost:3000/auth/slack/callback',
path: '/auth/slack',
scope: 'identity.basic,identity.team,identity.avatar'
};

const slackAuth = microAuthSlack(options);

// Third `auth` argument will provide error or result of authentication
// so it will { err: errorObject} or { result: {
// provider: 'slack',
// accessToken: 'blahblah',
// info: userInfo
// }}
const handler = async (req, res, auth) => {

if (!auth) {
return send(res, 404, 'Not Found');
}

if (auth.err) {
// Error handler
console.error(auth.err);
return send(res, 403, 'Forbidden');
}

// Save something in database here

return `Hello ${auth.result.info.user.name}`;

};

module.exports = slackAuth(handler);

```

Run:
```sh
micro app.js
```

Now visit `http://localhost:3000/auth/slack`


## Author
[Artem Karpovich](https://github.com/artemkarpovich)
32 changes: 32 additions & 0 deletions example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const { send } = require('micro');
const microAuthSlack = require('./index');

const options = {
clientId: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET',
callbackUrl: 'http://localhost:3000/auth/slack/callback',
path: '/auth/slack',
scope: 'identity.basic,identity.team,identity.avatar'
};

const slackAuth = microAuthSlack(options);

const handler = async (req, res, auth) => {

if (!auth) {
return send(res, 404, 'Not Found');
}

if (auth.err) {
// Error handler
console.error(auth.err);
return send(res, 403, 'Forbidden');
}

// Save something in database here

return `Hello ${auth.result.info.user.name}`;

};

module.exports = slackAuth(handler);
90 changes: 90 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
const querystring = require('querystring');
const url = require('url');

const uuid = require('uuid');
const rp = require('request-promise');
const redirect = require('micro-redirect');

const provider = 'slack';

const microAuthSlack = ({ clientId, clientSecret, callbackUrl, path = '/auth/slack', scope = 'identity.basic' }) => {
const getRedirectUrl = state => {
return `https://slack.com/oauth/authorize?client_id=${clientId}&redirect_uri=${callbackUrl}&scope=${scope}&state=${state}`;
};

const states = [];

return fn => async (req, res, ...args) => {
const { pathname, query } = url.parse(req.url);

if (pathname === path) {
try {
const state = uuid.v4();
const redirectUrl = getRedirectUrl(state);
states.push(state);
return redirect(res, 302, redirectUrl);
} catch (err) {
args.push({ err, provider });
return fn(req, res, ...args);
}
}

const callbackPath = url.parse(callbackUrl).pathname;
if (pathname === callbackPath) {
try {
const { state, code } = querystring.parse(query);

if (!states.includes(state)) {
const err = new Error('Invalid state');
args.push({ err, provider });
return fn(req, res, ...args);
}

states.splice(states.indexOf(state), 1);

const response = await rp({
url: 'https://slack.com/api/oauth.access',
qs: {
// eslint-disable-next-line camelcase
client_id: clientId,
// eslint-disable-next-line camelcase
client_secret: clientSecret,
code
},
json: true
});

if (response.error) {
args.push({ err: response.error, provider });
return fn(req, res, ...args);
}

const accessToken = response.access_token;

const user = await rp({
url: 'https://slack.com/api/users.identity',
qs: {
token: accessToken
},
json: true
});

const result = {
provider,
accessToken,
info: user
};

args.push({ result });
return fn(req, res, ...args);
} catch (err) {
args.push({ err, provider });
return fn(req, res, ...args);
}
}

return fn(req, res, ...args)
}
};

module.exports = microAuthSlack;
33 changes: 33 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "microauth-slack",
"version": "0.0.0",
"description": "Slack oauth for micro",
"main": "index.js",
"scripts": {
"example": "micro example.js",
"test": "xo"
},
"repository": {
"type": "git",
"url": "https://github.com/microauth/microauth-slack"
},
"author": "Artem Karpovich",
"license": "MIT",
"devDependencies": {
"eslint-config-prettier": "^1.6.0",
"xo": "^0.18.1"
},
"peerDependencies": {
"micro": "^7.3.2"
},
"dependencies": {
"micro-redirect": "^1.0.0",
"request": "^2.81.0",
"request-promise": "^4.2.0",
"uuid": "^3.0.1"
},
"xo": {
"spaces": 2,
"extends": "prettier"
}
}
Loading

0 comments on commit 5d823d5

Please sign in to comment.