-
Notifications
You must be signed in to change notification settings - Fork 44
Use electron-proxy-agent #878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* eslint standard/no-callback-literal: 0 */ | ||
|
||
const ElectronProxyAgent = require('electron-proxy-agent') | ||
const url = require('url') | ||
const http = require('http') | ||
const https = require('https') | ||
|
||
const log = require('cozy-desktop').default.logger({ | ||
component: 'GUI:proxy' | ||
}) | ||
|
||
const config = require('yargs') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not reuse There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was in the CLI package and I am scared of the dark voodoo between cli & gui if they use the same package 😃 |
||
.env('COZY_DRIVE') | ||
.conflicts('proxy-script', 'proxy-rules') | ||
.describe('proxy-script', 'The URL associated with the PAC file.') | ||
.describe('proxy-rules', 'Rules indicating which proxies to use.') | ||
.describe('proxy-bypassrules', 'Rules indicating which URLs should bypass the proxy settings. ' + | ||
'See https://github.com/electron/electron/blob/master/docs/api/session.md#sessetproxyconfig-callback') | ||
.default('proxy-ntlm-domains', '*') | ||
.describe('proxy-ntlm-domains', 'A comma-separated list of servers for which integrated authentication is enabled. ' + | ||
'Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate authentication.') | ||
.describe('login-by-realm', 'comma-separated list of realm:user:password') | ||
.help('help') | ||
.parse() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe move to main later? |
||
|
||
log.warn({config}, 'argv') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (not repeating, there are a few others below) |
||
|
||
const printCertificate = (certif) => `Certificate(${certif.issuerName} ${certif.subjectName})` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't really print anything.. |
||
|
||
module.exports = (app, session, doneSetup) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really export anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, this cant be initialized until There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course, we are exporting a function... Sorry, my bad :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (My brain was messing up with requirejs-like syntax...) |
||
const loginByRealm = {} | ||
if (config['login-by-realm']) { | ||
config['login-by-realm'].split(',').forEach((lbr) => { | ||
const [realm, username, password] = lbr.split(':') | ||
loginByRealm[realm] = [username, password] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sure auth doesn't break when password contains a colon? const [realm, username, passwordParts] = lbr.split(':')
loginByRealm[realm] = [username, passwordParts.join(':')] |
||
}) | ||
} | ||
|
||
if (config['proxy-ntlm-domains']) { | ||
session.defaultSession.allowNTLMCredentialsForDomains(config['proxy-ntlm-domains']) | ||
} | ||
|
||
session.defaultSession.setCertificateVerifyProc((request, callback) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this for debug only? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep. Hopefully will give us more data for the bug we were speaking about tonight. |
||
const {hostname, certificate, verificationResult, errorCode} = request | ||
if (verificationResult < 0) { | ||
log.warn({hostname, certificate: printCertificate(certificate), verificationResult, errorCode}, 'Certificate Verification Error') | ||
} else { | ||
log.debug({hostname, certificate: printCertificate(certificate), verificationResult, errorCode}, 'Certificate Validated') | ||
} | ||
callback(-3) // use chrome validation | ||
}) | ||
|
||
app.on('select-client-certificate', (event, webContents, url, list, callback) => { | ||
log.debug({url}, 'select-client-certificate') | ||
callback() | ||
}) | ||
|
||
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => { | ||
log.warn({url, error, certificate: printCertificate(certificate)}, 'App Certificate Error') | ||
callback(false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to callback(false) to not accept any certificate. |
||
}) | ||
|
||
app.on('login', (event, webContents, request, authInfo, callback) => { | ||
log.warn({request: request.method + ' ' + request.url, authInfo}, 'Login event') | ||
const auth = loginByRealm[authInfo.realm] | ||
if (auth) { | ||
event.preventDefault() | ||
callback(...auth) | ||
} else { | ||
callback() | ||
} | ||
}) | ||
|
||
const electronFetch = require('electron-fetch') | ||
global.fetch = (url, opts = {}) => { | ||
opts.session = session.defaultSession | ||
return electronFetch(url, opts) | ||
} | ||
http.Agent.globalAgent = http.globalAgent = https.globalAgent = new ElectronProxyAgent(session.defaultSession) | ||
const _httpRequest = http.request | ||
http.request = function (options, cb) { | ||
log.warn(options, 'USING RAW HTTP REQUEST') | ||
options.agent = options.agent || http.globalAgent | ||
options.headers = options.headers || {} | ||
options.headers.host = options.hostname | ||
return _httpRequest.call(http, options, cb) | ||
} | ||
const _httpsRequest = https.request | ||
https.request = function (options, cb) { | ||
log.warn(options, 'USING RAW HTTPS REQUEST') | ||
if (typeof options === 'string') { | ||
options = url.parse(options) | ||
} else { | ||
options = Object.assign({}, options) | ||
} | ||
options.agent = options.agent || https.globalAgent | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why doesn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, thanks for the explanation! |
||
return _httpsRequest.call(https, options, cb) | ||
} | ||
|
||
if (config['proxy-script'] || config['proxy-rules']) { | ||
session.defaultSession.setProxy({ | ||
pacScript: config['proxy-script'], | ||
proxyRules: config['proxy-rules'], | ||
proxyBypassRules: config['proxy-bypassrules'] | ||
}, doneSetup) | ||
} else doneSetup() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes me think that CLI won't have proxy support. Not a priority though. We'll just need to make it clear in case we bring it back.