add CA download page

This commit is contained in:
guox191 2019-03-26 14:11:22 +08:00
parent 15d7ed48bf
commit 7f02664079
7 changed files with 116 additions and 61 deletions

View File

@ -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 -> 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

View File

@ -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 -> 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

View File

@ -12,7 +12,8 @@ const express = require('express'),
wsServer = require('./wsServer'),
juicer = require('juicer'),
ip = require('ip'),
compress = require('compression');
compress = require('compression'),
pug = require('pug');
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) => {
res.setHeader('Access-Control-Allow-Origin', '*');
const _crtFilePath = certMgr.getRootCAFilePath();
@ -219,9 +225,8 @@ class webInterface extends events.EventEmitter {
app.get('/api/getQrCode', (req, res) => {
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 targetUrl = req.protocol + '://' + req.get('host') + '/fetchCrtFile?type=' + fileType;
const targetUrl = req.protocol + '://' + req.get('host') + '/downloadCrt';
const isRootCAFileExists = certMgr.isRootCAFileExists();
qr.addData(targetUrl);

View 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';
});

View File

@ -17,26 +17,12 @@ describe('WebInterface server', () => {
webServer.close();
});
it('should support change CA extensions in /getQrCode', done => {
const certFileTypes = ['crt', 'cer', 'pem', 'der'];
const tasks = certFileTypes.map((type) => {
return directGet(`${webHost}/api/getQrCode`, { type })
.then(res => {
const body = JSON.parse(res.body);
expect(body.qrImgDom).toMatch('<img src="data:image/');
expect(body.url).toBe(`${webHost}/fetchCrtFile?type=${type}`);
});
});
Promise.all(tasks)
.then(done)
.catch(done);
});
it('should fallback to .crt file in /getQrCode', done => {
directGet(`${webHost}/api/getQrCode`, { type: 'unkonw' })
it('should response qrcode string in /getQrCode', done => {
directGet(`${webHost}/api/getQrCode`)
.then(res => {
expect(JSON.parse(res.body).url).toBe(`${webHost}/fetchCrtFile?type=crt`);
const body = JSON.parse(res.body);
expect(body.qrImgDom).toMatch('<img src="data:image/');
expect(body.url).toBe(`${webHost}/downloadCrt`);
done();
})
.catch(done);

View File

@ -5,29 +5,26 @@
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import ClassBind from 'classnames/bind';
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 { hideRootCA, updateIsRootCAExists } from 'action/globalStatusAction';
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 CommonStyle from '../style/common.less';
const certFileTypes = ['crt', 'cer', 'pem', 'der'];
class DownloadRootCA extends React.Component {
constructor () {
super();
this.state = {
loadingCAQr: false,
generatingCA: false,
fileType: certFileTypes[0]
generatingCA: false
};
this.onClose = this.onClose.bind(this);
this.onFileTypeChange = this.onFileTypeChange.bind(this);
this.getQrCodeContent = this.getQrCodeContent.bind(this);
}
@ -41,7 +38,7 @@ class DownloadRootCA extends React.Component {
loadingCAQr: true
});
getJSON('/api/getQrCode', { type: this.state.fileType })
getJSON('/api/getQrCode')
.then((response) => {
this.setState({
loadingCAQr: false,
@ -60,33 +57,12 @@ class DownloadRootCA extends React.Component {
this.props.dispatch(hideRootCA());
}
onFileTypeChange (value) {
this.setState({
fileType: value
}, () => {
this.fetchData();
});
}
getQrCodeContent () {
const imgDomContent = { __html: this.state.CAQrCodeImageDom };
const content = (
<div className={Style.qrCodeWrapper} >
<div dangerouslySetInnerHTML={imgDomContent} />
<div>Scan to download rootCA.{this.state.fileType} to your Phone</div>
<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>
<span>Scan to download rootCA to your Phone</span>
</div>
);
@ -95,6 +71,7 @@ class DownloadRootCA extends React.Component {
}
getGenerateRootCADiv () {
const doToggleRemoteIntercept = () => {
postJSON('/api/generateRootCA')
.then((result) => {
@ -150,8 +127,8 @@ class DownloadRootCA extends React.Component {
</div>
<div className={Style.buttons} >
<a href={`/fetchCrtFile?type=${this.state.fileType}`} target="_blank">
<Button type="primary" size="large" >Download</Button>
<a href="/fetchCrtFile" target="_blank">
<Button type="primary" size="large" > Download </Button>
</a>
<span className={Style.tipSpan} >Or click the button to download.</span>
</div>
@ -169,6 +146,7 @@ class DownloadRootCA extends React.Component {
return (
<ResizablePanel onClose={this.onClose} visible={panelVisible} >
{this.props.globalStatus.isRootCAFileExists ? this.getDownloadDiv() : this.getGenerateRootCADiv()}
</ResizablePanel>
);
}

View File

@ -55,9 +55,4 @@
margin-top: 18px;
display: block;
}
}
.fileSelect {
width: 60px;
margin-left: 8px;
}