mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-04-24 16:51:29 +00:00
add CA download page
This commit is contained in:
parent
15d7ed48bf
commit
7f02664079
@ -820,7 +820,7 @@ Installing CA in Android could be different based on the system, we list some co
|
|||||||
* Settings -> Security & Location > Encryption & credentials -> Install from storage, and find your CA file to install
|
* Settings -> Security & Location > Encryption & credentials -> Install from storage, and find your CA file to install
|
||||||
* Settings -> Security -> Install from SD card, and find you CA file to install
|
* Settings -> Security -> Install from SD card, and find you CA file to install
|
||||||
|
|
||||||
As we konw, there are several file extensions of CA file which may not recognised by all kinds of Android OS. The .crt file is the most popular, and a few systems only support .cer file such as OPPO R15. In AnyProxy, you can choose what type of file you need before installing the root CA to your devices.
|
As we known, there are several file extensions of CA file which may not be recognised by all kinds of Android. The .crt file is the most popular, and a few systems only support .cer file such as OPPO R15. In AnyProxy, you can choose the type of file you need before installing the root CA to your devices.
|
||||||
|
|
||||||
### config iOS/Android proxy server
|
### config iOS/Android proxy server
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ Installing CA in Android could be different based on the system, we list some co
|
|||||||
* Settings -> Security & Location > Encryption & credentials -> Install from storage, and find your CA file to install
|
* Settings -> Security & Location > Encryption & credentials -> Install from storage, and find your CA file to install
|
||||||
* Settings -> Security -> Install from SD card, and find you CA file to install
|
* Settings -> Security -> Install from SD card, and find you CA file to install
|
||||||
|
|
||||||
As we konw, there are several file extensions of CA file which may not recognised by all kinds of Android OS. The .crt file is the most popular, and a few systems only support .cer file such as OPPO R15. In AnyProxy, you can choose what type of file you need before installing the root CA to your devices.
|
As we known, there are several file extensions of CA file which may not be recognised by all kinds of Android. The .crt file is the most popular, and a few systems only support .cer file such as OPPO R15. In AnyProxy, you can choose the type of file you need before installing the root CA to your devices.
|
||||||
|
|
||||||
### config iOS/Android proxy server
|
### config iOS/Android proxy server
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ const express = require('express'),
|
|||||||
wsServer = require('./wsServer'),
|
wsServer = require('./wsServer'),
|
||||||
juicer = require('juicer'),
|
juicer = require('juicer'),
|
||||||
ip = require('ip'),
|
ip = require('ip'),
|
||||||
compress = require('compression');
|
compress = require('compression'),
|
||||||
|
pug = require('pug');
|
||||||
|
|
||||||
const DEFAULT_WEB_PORT = 8002; // port for web interface
|
const DEFAULT_WEB_PORT = 8002; // port for web interface
|
||||||
|
|
||||||
@ -202,6 +203,11 @@ class webInterface extends events.EventEmitter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get('/downloadCrt', (req, res) => {
|
||||||
|
const pageFn = pug.compileFile(path.join(__dirname, '../resource/cert_download.pug'));
|
||||||
|
res.end(pageFn({ ua: req.get('user-agent') }));
|
||||||
|
});
|
||||||
|
|
||||||
app.get('/fetchCrtFile', (req, res) => {
|
app.get('/fetchCrtFile', (req, res) => {
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
const _crtFilePath = certMgr.getRootCAFilePath();
|
const _crtFilePath = certMgr.getRootCAFilePath();
|
||||||
@ -219,9 +225,8 @@ class webInterface extends events.EventEmitter {
|
|||||||
app.get('/api/getQrCode', (req, res) => {
|
app.get('/api/getQrCode', (req, res) => {
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
|
||||||
const fileType = certFileTypes.indexOf(req.query.type) !== -1 ? req.query.type : 'crt';
|
|
||||||
const qr = qrCode.qrcode(4, 'M');
|
const qr = qrCode.qrcode(4, 'M');
|
||||||
const targetUrl = req.protocol + '://' + req.get('host') + '/fetchCrtFile?type=' + fileType;
|
const targetUrl = req.protocol + '://' + req.get('host') + '/downloadCrt';
|
||||||
const isRootCAFileExists = certMgr.isRootCAFileExists();
|
const isRootCAFileExists = certMgr.isRootCAFileExists();
|
||||||
|
|
||||||
qr.addData(targetUrl);
|
qr.addData(targetUrl);
|
||||||
|
91
resource/cert_download.pug
Normal file
91
resource/cert_download.pug
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
doctype html
|
||||||
|
html(lang="en")
|
||||||
|
head
|
||||||
|
title Download rootCA
|
||||||
|
meta(name='viewport', content='initial-scale=1, maximum-scale=0.5, minimum-scale=1, user-scalable=no')
|
||||||
|
style.
|
||||||
|
body {
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-size: 36px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.any {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.proxy {
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 20px 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px 15px 5px 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 32px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
border-color: #108ee9;
|
||||||
|
color: rgba(0, 0, 0, .65);
|
||||||
|
background-color: #fff;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.primary {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #108ee9;
|
||||||
|
border-color: #108ee9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
word-break: break-all;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
body
|
||||||
|
.logo
|
||||||
|
span.any Any
|
||||||
|
span.proxy Proxy
|
||||||
|
.title Download:
|
||||||
|
.content Select a CA file to download, the .crt file is commonly used.
|
||||||
|
a(href="/fetchCrtFile?type=crt").button.primary rootCA.crt
|
||||||
|
a(href="/fetchCrtFile?type=cer").button rootCA.cer
|
||||||
|
.more More
|
||||||
|
.buttons(style='display: none')
|
||||||
|
a(href="/fetchCrtFile?type=pem").button rootCA.pem
|
||||||
|
a(href="/fetchCrtFile?type=der").button rootCA.der
|
||||||
|
.title User-Agent:
|
||||||
|
.content #{ua}
|
||||||
|
script(type='text/javascript').
|
||||||
|
window.document.querySelector('.more').addEventListener('click', function (e) {
|
||||||
|
e.target.style.display = 'none';
|
||||||
|
window.document.querySelector('.buttons').style.display = 'block';
|
||||||
|
});
|
@ -17,26 +17,12 @@ describe('WebInterface server', () => {
|
|||||||
webServer.close();
|
webServer.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support change CA extensions in /getQrCode', done => {
|
it('should response qrcode string in /getQrCode', done => {
|
||||||
const certFileTypes = ['crt', 'cer', 'pem', 'der'];
|
directGet(`${webHost}/api/getQrCode`)
|
||||||
const tasks = certFileTypes.map((type) => {
|
|
||||||
return directGet(`${webHost}/api/getQrCode`, { type })
|
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const body = JSON.parse(res.body);
|
const body = JSON.parse(res.body);
|
||||||
expect(body.qrImgDom).toMatch('<img src="data:image/');
|
expect(body.qrImgDom).toMatch('<img src="data:image/');
|
||||||
expect(body.url).toBe(`${webHost}/fetchCrtFile?type=${type}`);
|
expect(body.url).toBe(`${webHost}/downloadCrt`);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Promise.all(tasks)
|
|
||||||
.then(done)
|
|
||||||
.catch(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fallback to .crt file in /getQrCode', done => {
|
|
||||||
directGet(`${webHost}/api/getQrCode`, { type: 'unkonw' })
|
|
||||||
.then(res => {
|
|
||||||
expect(JSON.parse(res.body).url).toBe(`${webHost}/fetchCrtFile?type=crt`);
|
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(done);
|
.catch(done);
|
||||||
|
@ -5,29 +5,26 @@
|
|||||||
|
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import ClassBind from 'classnames/bind';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { message, Button, Spin, Select } from 'antd';
|
import { message, Button, Spin } from 'antd';
|
||||||
import ResizablePanel from 'component/resizable-panel';
|
import ResizablePanel from 'component/resizable-panel';
|
||||||
import { hideRootCA, updateIsRootCAExists } from 'action/globalStatusAction';
|
import { hideRootCA, updateIsRootCAExists } from 'action/globalStatusAction';
|
||||||
import { MenuKeyMap } from 'common/Constant';
|
import { MenuKeyMap } from 'common/Constant';
|
||||||
import { getJSON, postJSON } from 'common/ApiUtil';
|
import { getJSON, ajaxGet, postJSON } from 'common/ApiUtil';
|
||||||
|
|
||||||
import Style from './download-root-ca.less';
|
import Style from './download-root-ca.less';
|
||||||
import CommonStyle from '../style/common.less';
|
import CommonStyle from '../style/common.less';
|
||||||
|
|
||||||
const certFileTypes = ['crt', 'cer', 'pem', 'der'];
|
|
||||||
|
|
||||||
class DownloadRootCA extends React.Component {
|
class DownloadRootCA extends React.Component {
|
||||||
constructor () {
|
constructor () {
|
||||||
super();
|
super();
|
||||||
this.state = {
|
this.state = {
|
||||||
loadingCAQr: false,
|
loadingCAQr: false,
|
||||||
generatingCA: false,
|
generatingCA: false
|
||||||
fileType: certFileTypes[0]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onClose = this.onClose.bind(this);
|
this.onClose = this.onClose.bind(this);
|
||||||
this.onFileTypeChange = this.onFileTypeChange.bind(this);
|
|
||||||
this.getQrCodeContent = this.getQrCodeContent.bind(this);
|
this.getQrCodeContent = this.getQrCodeContent.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +38,7 @@ class DownloadRootCA extends React.Component {
|
|||||||
loadingCAQr: true
|
loadingCAQr: true
|
||||||
});
|
});
|
||||||
|
|
||||||
getJSON('/api/getQrCode', { type: this.state.fileType })
|
getJSON('/api/getQrCode')
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loadingCAQr: false,
|
loadingCAQr: false,
|
||||||
@ -60,33 +57,12 @@ class DownloadRootCA extends React.Component {
|
|||||||
this.props.dispatch(hideRootCA());
|
this.props.dispatch(hideRootCA());
|
||||||
}
|
}
|
||||||
|
|
||||||
onFileTypeChange (value) {
|
|
||||||
this.setState({
|
|
||||||
fileType: value
|
|
||||||
}, () => {
|
|
||||||
this.fetchData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getQrCodeContent () {
|
getQrCodeContent () {
|
||||||
const imgDomContent = { __html: this.state.CAQrCodeImageDom };
|
const imgDomContent = { __html: this.state.CAQrCodeImageDom };
|
||||||
const content = (
|
const content = (
|
||||||
<div className={Style.qrCodeWrapper} >
|
<div className={Style.qrCodeWrapper} >
|
||||||
<div dangerouslySetInnerHTML={imgDomContent} />
|
<div dangerouslySetInnerHTML={imgDomContent} />
|
||||||
<div>Scan to download rootCA.{this.state.fileType} to your Phone</div>
|
<span>Scan to download rootCA to your Phone</span>
|
||||||
<div>You can change the CA's file extension:
|
|
||||||
<Select
|
|
||||||
defaultValue={this.state.fileType}
|
|
||||||
className={Style.fileSelect}
|
|
||||||
onChange={this.onFileTypeChange}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
certFileTypes.map(key => (
|
|
||||||
<Option key={key} value={key}>{key}</Option>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -95,6 +71,7 @@ class DownloadRootCA extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getGenerateRootCADiv () {
|
getGenerateRootCADiv () {
|
||||||
|
|
||||||
const doToggleRemoteIntercept = () => {
|
const doToggleRemoteIntercept = () => {
|
||||||
postJSON('/api/generateRootCA')
|
postJSON('/api/generateRootCA')
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
@ -150,8 +127,8 @@ class DownloadRootCA extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={Style.buttons} >
|
<div className={Style.buttons} >
|
||||||
<a href={`/fetchCrtFile?type=${this.state.fileType}`} target="_blank">
|
<a href="/fetchCrtFile" target="_blank">
|
||||||
<Button type="primary" size="large" >Download</Button>
|
<Button type="primary" size="large" > Download </Button>
|
||||||
</a>
|
</a>
|
||||||
<span className={Style.tipSpan} >Or click the button to download.</span>
|
<span className={Style.tipSpan} >Or click the button to download.</span>
|
||||||
</div>
|
</div>
|
||||||
@ -169,6 +146,7 @@ class DownloadRootCA extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<ResizablePanel onClose={this.onClose} visible={panelVisible} >
|
<ResizablePanel onClose={this.onClose} visible={panelVisible} >
|
||||||
{this.props.globalStatus.isRootCAFileExists ? this.getDownloadDiv() : this.getGenerateRootCADiv()}
|
{this.props.globalStatus.isRootCAFileExists ? this.getDownloadDiv() : this.getGenerateRootCADiv()}
|
||||||
|
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,3 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fileSelect {
|
|
||||||
width: 60px;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user