Skip to content

Commit

Permalink
chore: import last existing code from sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
hfreire committed May 27, 2017
1 parent d9dead7 commit fc479c0
Show file tree
Hide file tree
Showing 20 changed files with 1,114 additions and 281 deletions.
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@
"dependencies": {
"aws-sdk": "2.58.0",
"bluebird": "3.5.0",
"bluebird-retry": "0.10.1",
"brakes": "2.5.3",
"health-checkup": "1.0.8",
"lodash": "4.17.4",
"modern-logger": "1.3.7",
"nightmare": "2.10.0",
"random-http-useragent": "1.1.0",
"request": "2.81.0",
"serverful": "1.0.22",
"sqlite3": "^3.1.8",
"sqlite3": "3.1.8",
"tinder": "1.19.0",
"uuid": "^3.0.1"
"uuid": "3.0.1"
},
"devDependencies": {
"babel-eslint": "7.2.3",
Expand Down
107 changes: 107 additions & 0 deletions src/auth/facebook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2017, Hugo Freire <hugo@exec.sh>.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/

const _ = require('lodash')
const Promise = require('bluebird')
const retry = require('bluebird-retry')
const Brakes = require('brakes')

const Nightmare = require('nightmare')
Nightmare.Promise = Promise

const Logger = require('modern-logger')

const Health = require('health-checkup')

const RandomUserAgent = require('random-http-useragent')

const { join } = require('path')

const authorizeApp = function (email, password, url, userAgent) {
let facebookUserId
let accessToken

const nightmare = Nightmare(this._options.nightmare)

return nightmare
.useragent(userAgent)
.on('page', function (type, url, method, response) {
if (type !== 'xhr-complete') {
return
}

if (url.path === '/ajax/presence/reconnect.php') {
const match = response.match(/"user_channel":"p_(.*?)"/)
facebookUserId = match.length === 2 ? match[ 1 ] : undefined

return
}

if (_.includes(url, 'oauth/confirm?dpr')) {
const match = response.match(/access_token=(.*)&/)
accessToken = match.length === 2 ? match[ 1 ] : undefined
}
})
.goto('https://facebook.com')
.type('input#email', email)
.type('input#pass', password)
.click('#loginbutton input')
.wait(3000)
.goto(url)
.wait('button._42ft._4jy0.layerConfirm._1flv._51_n.autofocus.uiOverlayButton._4jy5._4jy1.selected._51sy')
.click('button._42ft._4jy0.layerConfirm._1flv._51_n.autofocus.uiOverlayButton._4jy5._4jy1.selected._51sy')
.wait(10000)
.end()
.then(() => {
if (!accessToken || !facebookUserId) {
throw new Error('unable to authorize app')
}

return { accessToken, facebookUserId }
})
}

const defaultOptions = {
nightmare: {
show: false,
partition: 'nopersist',
webPreferences: {
preload: join(__dirname, '/preload.js'),
webSecurity: false
}
},
retry: { max_tries: 2, interval: 5000, timeout: 40000, throw_original: true },
breaker: { timeout: 60000, threshold: 80, circuitDuration: 3 * 60 * 60 * 1000 }
}

class Facebook {
constructor (options = {}) {
this._options = _.defaults(options, defaultOptions)

this._breaker = new Brakes(this._options.breaker)

this._authorizeAppCircuitBreaker = this._breaker.slaveCircuit((...params) => retry(() => authorizeApp.bind(this)(...params), this._options.retry))

Health.addCheck('facebook', () => new Promise((resolve, reject) => {
if (this._breaker.isOpen()) {
return reject(new Error(`circuit breaker is open`))
} else {
return resolve()
}
}))
}

authorizeApp (email, password, url) {
Logger.debug('Started authorizing app in Facebook')

return RandomUserAgent.get()
.then((userAgent) => this._authorizeAppCircuitBreaker.exec(email, password, url, userAgent))
.finally(() => Logger.debug('Finished authorizing app in Facebook'))
}
}

module.exports = Facebook
10 changes: 10 additions & 0 deletions src/auth/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2017, Hugo Freire <hugo@exec.sh>.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/

module.exports = {
Facebook: require('./facebook')
}
88 changes: 88 additions & 0 deletions src/auth/preload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2017, Hugo Freire <hugo@exec.sh>.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/

/* eslint-disable no-undef */

window.__nightmare = {}
__nightmare.ipc = require('electron').ipcRenderer
__nightmare.sliced = require('sliced')

// Listen for error events
window.addEventListener('error', function (e) {
__nightmare.ipc.send('page', 'error', e.message, e.error.stack)
})

var open = window.XMLHttpRequest.prototype.open
window.XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
this.addEventListener('readystatechange', function () {
if (this.readyState === 4) {
__nightmare.ipc.send('page', 'xhr-complete', url, method, this.responseText)
}
}, false)
open.apply(this, arguments)
};

(function () {
// prevent 'unload' and 'beforeunload' from being bound
var defaultAddEventListener = window.addEventListener
window.addEventListener = function (type) {
if (type === 'unload' || type === 'beforeunload') {
return
}
defaultAddEventListener.apply(window, arguments)
}

// prevent 'onunload' and 'onbeforeunload' from being set
Object.defineProperties(window, {
onunload: {
enumerable: true,
writable: false,
value: null
},
onbeforeunload: {
enumerable: true,
writable: false,
value: null
}
})

// listen for console.log
var defaultLog = console.log
console.log = function () {
__nightmare.ipc.send('console', 'log', __nightmare.sliced(arguments))
return defaultLog.apply(this, arguments)
}

// listen for console.warn
var defaultWarn = console.warn
console.warn = function () {
__nightmare.ipc.send('console', 'warn', __nightmare.sliced(arguments))
return defaultWarn.apply(this, arguments)
}

// listen for console.error
var defaultError = console.error
console.error = function () {
__nightmare.ipc.send('console', 'error', __nightmare.sliced(arguments))
return defaultError.apply(this, arguments)
}

// overwrite the default alert
window.alert = function (message) {
__nightmare.ipc.send('page', 'alert', message)
}

// overwrite the default prompt
window.prompt = function (message, defaultResponse) {
__nightmare.ipc.send('page', 'prompt', message, defaultResponse)
}

// overwrite the default confirm
window.confirm = function (message, defaultResponse) {
__nightmare.ipc.send('page', 'confirm', message, defaultResponse)
}
})()
118 changes: 0 additions & 118 deletions src/database.js

This file was deleted.

0 comments on commit fc479c0

Please sign in to comment.