mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-04-19 15:44:22 +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 -> 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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
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();
|
||||
});
|
||||
|
||||
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);
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -55,9 +55,4 @@
|
||||
margin-top: 18px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.fileSelect {
|
||||
width: 60px;
|
||||
margin-left: 8px;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user