-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 201a34b
Showing
25 changed files
with
1,358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"presets": [ | ||
["env", { | ||
"targets": { | ||
"browsers": [ | ||
"last 2 versions", | ||
"ios_saf >= 8", | ||
"ie >= 10", | ||
"chrome >= 49", | ||
"firefox >= 49", | ||
"> 1%" | ||
] | ||
}, | ||
"debug": false, | ||
"loose": true, | ||
"useBuiltIns": true | ||
}], | ||
"react" | ||
], | ||
"plugins": [ | ||
"transform-class-properties", | ||
[ | ||
"transform-object-rest-spread", | ||
{ "useBuiltIns": true } | ||
] | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.min.js | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"parser": "babel-eslint", | ||
"extends": ["standard", "standard-react"], | ||
"rules": { | ||
"jsx-quotes": 0 | ||
}, | ||
"env": { | ||
"jest": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const app = require('./server')() | ||
const port = process.env.PORT || 3000 | ||
app.listen(port, () => { | ||
console.log('Listening at http://localhost:' + port) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module.exports = class KeepAlive { | ||
constructor (callback, delay) { | ||
this.callback = callback | ||
this.delay = delay | ||
} | ||
|
||
start () { | ||
this.id = setInterval(this.callback, this.delay) | ||
} | ||
|
||
stop () { | ||
clearInterval(this.id) | ||
} | ||
|
||
reset () { | ||
this.stop() | ||
this.start() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
{ | ||
"name": "smee-server", | ||
"version": "0.0.3", | ||
"description": "", | ||
"author": "Jason Etcovitch <[email protected]> (https://github.com/JasonEtco)", | ||
"license": "ISC", | ||
"repository": "https://github.com/probot/smee.git", | ||
"scripts": { | ||
"start": "node ./index.js", | ||
"start-dev": "concurrently \"nodemon --ignore src/ ./index.js\" \"webpack -w\"", | ||
"build": "webpack -p", | ||
"test": "jest --coverage && eslint", | ||
"postinstall": "npm run build" | ||
}, | ||
"dependencies": { | ||
"autoprefixer": "^7.1.6", | ||
"babel-core": "^6.26.0", | ||
"babel-eslint": "^7.2.3", | ||
"babel-loader": "^7.1.2", | ||
"babel-plugin-transform-class-properties": "^6.24.1", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"babel-preset-react": "^6.24.1", | ||
"connect-sse": "^1.2.0", | ||
"copy-to-clipboard": "^3.0.8", | ||
"copy-webpack-plugin": "^4.2.0", | ||
"crypto": "^1.0.1", | ||
"css-loader": "^0.28.7", | ||
"eventsource": "^1.0.5", | ||
"express": "^4.16.2", | ||
"express-sslify": "^1.2.0", | ||
"extract-text-webpack-plugin": "^3.0.1", | ||
"get-value": "^2.0.6", | ||
"glob-all": "^3.1.0", | ||
"helmet": "^3.9.0", | ||
"highlight.js": "^9.12.0", | ||
"html-webpack-plugin": "^2.30.1", | ||
"moment": "^2.19.1", | ||
"moment-timezone": "^0.5.14", | ||
"node-sass": "^4.5.3", | ||
"postcss-loader": "^2.0.8", | ||
"primer-css": "^9.6.0", | ||
"prop-types": "^15.6.0", | ||
"purify-css": "^1.2.5", | ||
"purifycss-webpack": "^0.7.0", | ||
"react": "^16.0.0", | ||
"react-dom": "^16.0.0", | ||
"react-json-view": "^1.13.2", | ||
"react-octicons": "^0.2.0", | ||
"sass-loader": "^6.0.6", | ||
"style-loader": "^0.19.0", | ||
"webpack": "^3.8.1" | ||
}, | ||
"devDependencies": { | ||
"babel-jest": "^21.2.0", | ||
"concurrently": "^3.5.0", | ||
"enzyme": "^3.2.0", | ||
"enzyme-adapter-react-16": "^1.1.0", | ||
"eslint-config-standard": "^10.2.1", | ||
"eslint-config-standard-react": "^5.0.0", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-node": "^5.2.1", | ||
"eslint-plugin-promise": "^3.6.0", | ||
"eslint-plugin-react": "^7.5.1", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"jest": "^21.2.1", | ||
"nodemon": "^1.12.1", | ||
"raf": "^3.4.0", | ||
"react-test-renderer": "^16.2.0", | ||
"standard": "^10.0.3", | ||
"supertest": "^3.0.0" | ||
}, | ||
"engines": { | ||
"node": "8.9.1" | ||
}, | ||
"jest": { | ||
"setupFiles": [ | ||
"./tests/setup.js" | ||
], | ||
"testPathIgnorePatterns": [ | ||
"/node_modules/" | ||
] | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>smee.io</title> | ||
<link rel="shortcut icon" href="/public/favicon.png"> | ||
<link rel="stylesheet" href="/public/main.min.css"> | ||
</head> | ||
<body> | ||
<header class="text-white text-center p-responsive bg-blue d-flex flex-column flex-items-center flex-justify-center" style="height: 80vh"> | ||
<div class="header__anim"> | ||
<div class="header__anim__payload"></div> | ||
<div class="header__anim__line"></div> | ||
<div class="header__anim__circle header__anim__center"></div> | ||
<div class="header__anim__circle header__anim__dashed-circle"></div> | ||
</div> | ||
<h1 class="f00-light">smee.io</h1> | ||
<h2 class="blue-700">Webhook payload delivery service</h2> | ||
<p class="lead text-white" style="opacity: 0.8">Receives payloads then sends them to your locally running application.</p> | ||
<a href="/new" class="btn btn-outline btn-outline-blue">Start a new channel</a> | ||
</header> | ||
|
||
<main class="container-lg py-6 mt-6 p-responsive"> | ||
<p class="lead text-center col-12 col-md-8 mx-auto">If your application needs to respond to webhooks, you'll need some way to expose <strong>localhost</strong> to the internet. <strong>smee.io</strong> is a small service that uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events" target="_blank" rel="noopener noreferrer">Server-Sent Events</a> to proxy payloads from the webhook source, then transmit them to your locally running application.</p> | ||
|
||
<div class="main__anim my-6"> | ||
<div class="main__anim__circle main__anim__left"> | ||
<span>Webhook Emitter</span> | ||
</div> | ||
<div class="main__anim__circle main__anim__right"> | ||
<span>localhost</span> | ||
</div> | ||
<div class="main__anim__line"></div> | ||
<div class="main__anim__payload"></div> | ||
<div class="main__anim__circle main__anim__center"> | ||
<span></span> | ||
</div> | ||
</div> | ||
|
||
<p class="lead text-center col-12 col-md-8 mx-auto">Tell your webhook source to send payloads to your <strong>smee.io</strong> channel, then either use the <a href="https://npmjs.com/package/smee-cli" target="_blank" rel="noopener noreferrer">smee CLI</a> or, if you're using <a href="https://probot.github.io" target="_blank" rel="noopener noreferrer">Probot</a> to build a GitHub App, just <a href="https://probot.github.io/docs/webhooks/">set the environment variable</a>.</p> | ||
</main> | ||
|
||
<footer class="border-top text-center py-4"> | ||
Made with 🤖 by the <a href="https://github.com/probot" target="_blank" rel="noopener noreferrer">Probot team</a>. | ||
</footer> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>Webhooks</title> | ||
<link rel="shortcut icon" href="/public/favicon.png"> | ||
<link rel="stylesheet" href="/public/main.min.css"> | ||
</head> | ||
<body> | ||
<noscript> | ||
<div class="no-script"> | ||
<h1>You must enable JavaScript to use try out todo.</h1> | ||
<a href="https://github.com/probot/webhooks/issues" target="_blank" rel="noopener noreferrer">Need help?</a> | ||
</div> | ||
</noscript> | ||
<div class="mount"></div> | ||
<script src="/public/main.min.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const sse = require('connect-sse')() | ||
const express = require('express') | ||
const crypto = require('crypto') | ||
const bodyParser = require('body-parser') | ||
const EventEmitter = require('events') | ||
const path = require('path') | ||
|
||
const KeepAlive = require('./keep-alive') | ||
|
||
// Tiny logger to prevent logs in tests | ||
const log = process.env.NODE_ENV === 'test' ? _ => _ : console.log | ||
|
||
module.exports = () => { | ||
const events = new EventEmitter() | ||
const app = express() | ||
const pubFolder = path.join(__dirname, 'public') | ||
|
||
if (process.env.FORCE_HTTPS) { | ||
app.use(require('helmet')()) | ||
app.use(require('express-sslify').HTTPS({ trustProtoHeader: true })) | ||
} | ||
|
||
app.use(bodyParser.json()) | ||
app.use('/public', express.static(pubFolder)) | ||
|
||
app.get('/', (req, res) => { | ||
res.sendFile(path.join(pubFolder, 'index.html')) | ||
}) | ||
|
||
app.get('/new', (req, res) => { | ||
const protocol = req.headers['x-forwarded-proto'] || req.protocol | ||
const host = req.headers['x-forwarded-host'] || req.get('host') | ||
const channel = crypto | ||
.randomBytes(12) | ||
.toString('base64') | ||
.replace(/\+/g, '-') | ||
.replace(/\//g, '_') | ||
.replace(/=/g, '~') | ||
|
||
res.redirect(307, `${protocol}://${host}/${channel}`) | ||
}) | ||
|
||
app.get('/:channel', (req, res, next) => { | ||
if (req.accepts('html')) { | ||
res.sendFile(path.join(pubFolder, 'webhooks.html')) | ||
} else { | ||
next() | ||
} | ||
}, sse, (req, res) => { | ||
function send (data) { | ||
res.json(data) | ||
keepAlive.reset() | ||
} | ||
|
||
function close () { | ||
events.removeListener(channel, send) | ||
keepAlive.stop() | ||
log('Client disconnected', channel, events.listenerCount(channel)) | ||
} | ||
|
||
const channel = req.params.channel | ||
|
||
// Setup interval to ping every 30 seconds to keep the connection alive | ||
const keepAlive = new KeepAlive(() => res.json({}, 'ping'), 30 * 1000) | ||
keepAlive.start() | ||
|
||
// Allow CORS | ||
res.setHeader('Access-Control-Allow-Origin', '*') | ||
|
||
// Listen for events on this channel | ||
events.on(channel, send) | ||
|
||
// Clean up when the client disconnects | ||
res.on('close', close) | ||
|
||
res.json({}, 'ready') | ||
|
||
log('Client connected', channel, events.listenerCount(channel)) | ||
}) | ||
|
||
app.post('/:channel', (req, res) => { | ||
events.emit(req.params.channel, { | ||
...req.headers, | ||
body: req.body, | ||
timestamp: Date.now() | ||
}) | ||
res.status(200).end() | ||
}) | ||
|
||
// Resend payload via the event emitter | ||
app.post('/:channel/redeliver', (req, res) => { | ||
events.emit(req.params.channel, req.body) | ||
res.status(200).end() | ||
}) | ||
|
||
return app | ||
} |
Oops, something went wrong.