mirror of
https://github.com/QuiteAFancyEmerald/Holy-Unblocker.git
synced 2025-05-17 13:30:01 -04:00
Replaced Node with Alloy locally.
This commit is contained in:
parent
a9683c8086
commit
53bc98d6f3
15 changed files with 889 additions and 353 deletions
71
README.md
71
README.md
|
@ -1,2 +1,69 @@
|
|||
# HolyUB
|
||||
A website that can be used to bypass web filters; both online and firewall.
|
||||
# Alloy Proxy
|
||||
|
||||
A node.js proxy that features URL encoding, and amazing compatablity!
|
||||
|
||||
[](https://heroku.com/deploy?template=https://github.com/titaniumnetwork-dev/alloyproxy/)
|
||||
|
||||
# How to install and use:
|
||||
|
||||
`git clone https://github.com/titaniumnetwork-dev/alloyproxy.git`
|
||||
|
||||
`cd alloyproxy`
|
||||
|
||||
`npm install`
|
||||
|
||||
`npm start`
|
||||
|
||||
The default place for the proxy when its started is `http://localhost:8080` but feel free to change it in config.json!
|
||||
|
||||
# How the proxy works:
|
||||
|
||||
The proxy works by using node-fetch (Basically Window.fetch ported to Node-js).
|
||||
Basically what the app is doing is node-fetch is sending the request to the server then
|
||||
the app sends the response back to the server with the modifactions made to the attributes and elements.
|
||||
|
||||
When a attribute is rewritten, depending on the contents inside. It will turn:
|
||||
|
||||
`href="/assets/js/main.js"` into `href="/fetch/websiteURL/assets/js/main.js"`.
|
||||
|
||||
A porition of its rewriting is in client-side JS so `Element.setAttribute`, `window.fetch()`, XMLHttpRequest, and more are rewritten.
|
||||
|
||||
# Extra information:
|
||||
|
||||
If your gonna have an external website redirect to this proxy. Then we recommend you have the value base64 encoded and redirected to `/alloy?url=` then value.
|
||||
|
||||
# Deploying to Heroku:
|
||||
|
||||
If your gonna be hosting this on something like Heroku. You need to make sure SSL mode is turned off so this will work.
|
||||
|
||||
# Known websites that work
|
||||
|
||||
- Google Search
|
||||
|
||||
- Discord
|
||||
|
||||
- LittleBigSnake
|
||||
|
||||
- Surviv.io
|
||||
|
||||
- Youtube
|
||||
|
||||
- Y8
|
||||
|
||||
- 1v1.LOL
|
||||
|
||||
- Old Reddit
|
||||
|
||||
and plenty more!
|
||||
|
||||
# Known issues that need to be fixed
|
||||
|
||||
- Better POST body parsing instead of using body-parser.
|
||||
|
||||
- Cookie header rewriting
|
||||
|
||||
# Updates to come in the future
|
||||
|
||||
- Full URL encoding / encryption mode
|
||||
|
||||
- Websocket proxing
|
||||
|
|
88
alloy/assets/error.html
Normal file
88
alloy/assets/error.html
Normal file
|
@ -0,0 +1,88 @@
|
|||
<html>
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
body {
|
||||
background-color: #222;
|
||||
font-family: "Roboto";
|
||||
color: #FFF;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
input {
|
||||
background-color: #111;
|
||||
color :#FFF;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
width: 300px;
|
||||
font-size: 19px;
|
||||
height: 45px;
|
||||
margin-bottom: 5px;
|
||||
font-family: 'Roboto';
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #3333cc;
|
||||
color :#FFF;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
width: 300px;
|
||||
font-size: 19px;
|
||||
height: 45px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
button:hover{
|
||||
cursor: pointer;
|
||||
background-color: #4d4dff;
|
||||
}
|
||||
|
||||
.container p {
|
||||
margin-bottom: 10px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
|
||||
.top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-bottom: #FFF solid 1px;
|
||||
}
|
||||
.top p {
|
||||
font-family: "Noto Sans JP";
|
||||
font-size: 30px;
|
||||
margin: 22px 22px;
|
||||
display: block
|
||||
}
|
||||
|
||||
#error {
|
||||
padding: 0px 5px;
|
||||
font-size: 22px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top">
|
||||
<p>AlloyProxy</p>
|
||||
</div>
|
||||
<p id="error">%ERROR%</p>
|
||||
</body>
|
||||
</html>
|
209
alloy/assets/inject.js
Normal file
209
alloy/assets/inject.js
Normal file
|
@ -0,0 +1,209 @@
|
|||
// Ajax Rewriting
|
||||
|
||||
let apData = document.getElementById('alloyData');
|
||||
let urlData = apData.getAttribute('data-alloyURL');
|
||||
|
||||
|
||||
function rewriteURL(url, encoding) {
|
||||
var websiteURL
|
||||
if (encoding == 'base64') {
|
||||
websiteURL = btoa(url.split('/').splice(0, 3).join('/'))
|
||||
} else {
|
||||
websiteURL = url.split('/').splice(0, 3).join('/')
|
||||
}
|
||||
const path = '/' + url.split('/').splice(3).join('/')
|
||||
var rewritten
|
||||
if (path == '/') {
|
||||
rewritten = '/fetch/' + websiteURL
|
||||
} else {
|
||||
rewritten = `/fetch/${websiteURL}${path}`
|
||||
}
|
||||
return rewritten
|
||||
}
|
||||
let ajaxRewrite = window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
|
||||
if (url.startsWith(`${window.location.protocol}//${window.location.hostname}`) && !url.startsWith(`${window.location.protocol}//${window.location.hostname}/fetch/`)) {
|
||||
url = `/fetch/${urlData}/` + url.split('/').splice(3).join('/')
|
||||
} else if (url.startsWith('http')) {
|
||||
const hostname = url.split('/').slice(0, 3).join('/')
|
||||
const path = url.split('/').slice(3).join('/')
|
||||
const encodedHost = btoa(hostname)
|
||||
const fullURL = encodedHost + '/' + path
|
||||
url = '/fetch/' + fullURL
|
||||
} else if (url.startsWith('//')) {
|
||||
const encodedURL = btoa('http:' + url)
|
||||
url = '/alloy/?url=' + encodedURL
|
||||
} else if (url.startsWith('/')) {
|
||||
if (url.startsWith('/fetch')) {
|
||||
url = url
|
||||
} else if (url.startsWith('/alloy')) {
|
||||
url = url
|
||||
} else {
|
||||
let apData = document.getElementById('alloyData');
|
||||
let urlData = apData.getAttribute('data-alloyURL');
|
||||
url = '/fetch/' + urlData + url
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ajaxRewrite.apply(this, arguments);
|
||||
}
|
||||
|
||||
let windowFetchRewrite = window.fetch;window.fetch = function(url) {
|
||||
if (url.startsWith(`https://${window.location.hostname}`)) {
|
||||
url = url
|
||||
} else if (url.startsWith('http')) {
|
||||
const hostname = url.split('/').slice(0, 3).join('/')
|
||||
const path = url.split('/').slice(3).join('/')
|
||||
const encodedHost = btoa(hostname)
|
||||
const fullURL = encodedHost + '/' + path
|
||||
url = '/fetch/' + fullURL
|
||||
} else if (url.startsWith('//')) {
|
||||
const encodedURL = btoa('http:' + url)
|
||||
url = '/alloy/?url=' + encodedURL
|
||||
} else if (url.startsWith('/')) {
|
||||
if (url.startsWith('/fetch')) {
|
||||
url = url
|
||||
} else if (url.startsWith('/alloy')) {
|
||||
url = url
|
||||
} else {
|
||||
let apData = document.getElementById('alloyData');
|
||||
let urlData = apData.getAttribute('data-alloyURL');
|
||||
url = '/fetch/' + urlData + url
|
||||
}
|
||||
}
|
||||
return windowFetchRewrite.apply(this, arguments);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Create Element rewriting
|
||||
var original = document.createElement;
|
||||
document.createElement = function (tag) {
|
||||
var element = original.call(document, tag);
|
||||
if (tag.toLowerCase() === 'script') {
|
||||
Object.defineProperty(element.__proto__, 'src', {
|
||||
set: function(newValue) {
|
||||
if (newValue.startsWith('/fetch/')) {
|
||||
element.setAttribute('src', newValue)
|
||||
} else if (newValue.startsWith('/alloy/')) {
|
||||
element.setAttribute('src', newValue)
|
||||
} else if (newValue.startsWith(`https://${window.location.hostname}`)) {
|
||||
element.setAttribute('src', newValue)
|
||||
} else if (newValue.startsWith('//')) {
|
||||
const encodedURL = btoa('http:' + newValue)
|
||||
element.setAttribute('src', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('https://')) {
|
||||
const encodedURL = btoa(newValue)
|
||||
element.setAttribute('src', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('http://')) {
|
||||
const encodedURL = btoa(newValue)
|
||||
element.setAttribute('src', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('/')) {
|
||||
element.setAttribute('src', '/fetch/' + urlData + newValue)
|
||||
} else {
|
||||
element.setAttribute('src', newValue)
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (tag.toLowerCase() === 'iframe') {
|
||||
Object.defineProperty(element.__proto__, 'src', {
|
||||
set: function(newValue) {
|
||||
if (newValue.startsWith('/fetch/')) {
|
||||
element.setAttribute('src', newValue)
|
||||
} else if (newValue.startsWith('/alloy/')) {
|
||||
element.setAttribute('src', newValue)
|
||||
} else if (newValue.startsWith(`https://${window.location.hostname}`)) {
|
||||
element.setAttribute('src', newValue)
|
||||
} else if (newValue.startsWith('//')) {
|
||||
const encodedURL = btoa('http:' + newValue)
|
||||
element.setAttribute('src', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('https://')) {
|
||||
const encodedURL = btoa(newValue)
|
||||
element.setAttribute('src', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('http://')) {
|
||||
const encodedURL = btoa(newValue)
|
||||
element.setAttribute('src', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('/')) {
|
||||
element.setAttribute('src', '/fetch/' + urlData + newValue)
|
||||
|
||||
} else {
|
||||
element.setAttribute('src', newValue)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (tag.toLowerCase() === 'link') {
|
||||
Object.defineProperty(element.__proto__, 'href', {
|
||||
set: function(newValue) {
|
||||
if (newValue.startsWith('/fetch/')) {
|
||||
element.setAttribute('href', newValue)
|
||||
} else if (newValue.startsWith('/alloy/')) {
|
||||
element.setAttribute('href', newValue)
|
||||
} else if (newValue.startsWith(`https://${window.location.hostname}`)) {
|
||||
element.setAttribute('href', newValue)
|
||||
} else if (newValue.startsWith('//')) {
|
||||
const encodedURL = btoa('http:' + newValue)
|
||||
element.setAttribute('href', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('https://')) {
|
||||
const encodedURL = btoa(newValue)
|
||||
element.setAttribute('href', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('http://')) {
|
||||
const encodedURL = btoa(newValue)
|
||||
element.setAttribute('href', '/alloy/?url=' + encodedURL)
|
||||
} else if (newValue.startsWith('/')) {
|
||||
element.setAttribute('href', '/fetch/' + urlData + newValue)
|
||||
|
||||
} else {
|
||||
element.setAttribute('href', newValue)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
let setAttributeRewrite = window.Element.prototype.setAttribute;window.Element.prototype.setAttribute = function(name, value) {
|
||||
switch(name) {
|
||||
case 'src':
|
||||
if (value.startsWith('/fetch/')) {
|
||||
value = value
|
||||
} else if (value.startsWith('/alloy/')) {
|
||||
value = value
|
||||
} else if (value.startsWith('//')) {
|
||||
value = rewriteURL('http:' + value, 'base64')
|
||||
} else if (value.startsWith('/')) {
|
||||
value = rewriteURL(urlData + value)
|
||||
break;
|
||||
} else if (value.startsWith('https://') || value.startsWith('http://')) {
|
||||
value = rewriteURL(value, 'base64')
|
||||
} else {
|
||||
value = value
|
||||
}
|
||||
break;
|
||||
case 'href':
|
||||
if (value.startsWith('/fetch/')) {
|
||||
value = value
|
||||
} else if (value.startsWith('//')) {
|
||||
value = rewriteURL('http:' + value, 'base64')
|
||||
} else if (value.startsWith('/')) {
|
||||
value = rewriteURL(urlData + value)
|
||||
break;
|
||||
} else if (value.startsWith('https://') || value.startsWith('http://')) {
|
||||
value = rewriteURL(value, 'base64')
|
||||
} else {
|
||||
value = value
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return setAttributeRewrite.apply(this, arguments);
|
||||
}
|
||||
|
||||
var previousState = window.history.state;
|
||||
setInterval(function() {
|
||||
if (!window.location.pathname.startsWith(`/fetch/${urlData}/`)) {
|
||||
history.replaceState('', '', `/fetch/${urlData}/${window.location.href.split('/').splice(3).join('/')}`);
|
||||
}
|
||||
}, 0.1);
|
403
app.js
403
app.js
|
@ -1,79 +1,334 @@
|
|||
/***************
|
||||
* node-unblocker: Web Proxy for evading firewalls and content filters,
|
||||
* similar to CGIProxy or PHProxy
|
||||
*
|
||||
*
|
||||
* This project is hosted on github: https://github.com/nfriedly/nodeunblocker.com
|
||||
*
|
||||
* By Nathan Friedly - http://nfriedly.com
|
||||
* Released under the terms of the Affero GPL v3
|
||||
*/
|
||||
|
||||
var url = require('url');
|
||||
var querystring = require('querystring');
|
||||
var https = require('https');
|
||||
var http = require('http');
|
||||
var fetch = require('node-fetch');
|
||||
var express = require('express');
|
||||
var unblocker = require('unblocker');
|
||||
var Transform = require('stream').Transform;
|
||||
|
||||
var fs = require('fs');
|
||||
var app = express();
|
||||
var cookieParser = require('cookie-parser');
|
||||
var session = require('express-session');
|
||||
|
||||
var google_analytics_id = process.env.GA_ID || null;
|
||||
|
||||
function addGa(html) {
|
||||
if (google_analytics_id) {
|
||||
var ga = [
|
||||
"<script type=\"text/javascript\">",
|
||||
"var _gaq = []; // overwrite the existing one, if any",
|
||||
"_gaq.push(['_setAccount', '" + google_analytics_id + "']);",
|
||||
"_gaq.push(['_trackPageview']);",
|
||||
"(function() {",
|
||||
" var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;",
|
||||
" ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';",
|
||||
" var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);",
|
||||
"})();",
|
||||
"</script>"
|
||||
].join("\n");
|
||||
html = html.replace("</body>", ga + "\n\n</body>");
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
function googleAnalyticsMiddleware(data) {
|
||||
if (data.contentType == 'text/html') {
|
||||
|
||||
// https://nodejs.org/api/stream.html#stream_transform
|
||||
data.stream = data.stream.pipe(new Transform({
|
||||
decodeStrings: false,
|
||||
transform: function(chunk, encoding, next) {
|
||||
this.push(addGa(chunk.toString()));
|
||||
next();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
var unblockerConfig = {
|
||||
prefix: '/call/',
|
||||
responseMiddleware: [
|
||||
googleAnalyticsMiddleware
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
|
||||
// this line must appear before any express.static calls (or anything else that sends responses)
|
||||
app.use(unblocker(unblockerConfig));
|
||||
|
||||
// serve up static files *after* the proxy is run
|
||||
app.use('/', express.static(__dirname + '/public'));
|
||||
|
||||
// this is for users who's form actually submitted due to JS being disabled or whatever
|
||||
app.get("/b", function(req, res) {
|
||||
// grab the "url" parameter from the querystring
|
||||
var site = querystring.parse(url.parse(req.url).query).url;
|
||||
// and redirect the user to /proxy/url
|
||||
res.redirect(unblockerConfig.prefix + site);
|
||||
var config = JSON.parse(fs.readFileSync('config.json', 'utf-8')),
|
||||
httpsAgent = new https.Agent({
|
||||
rejectUnauthorized: false,
|
||||
keepAlive: true,
|
||||
}),
|
||||
httpAgent = new http.Agent({
|
||||
rejectUnauthorized: false,
|
||||
keepAlive: true,
|
||||
}),
|
||||
ssl = { key: fs.readFileSync('ssl/default.key', 'utf8'), cert: fs.readFileSync('ssl/default.crt', 'utf8') },
|
||||
server,
|
||||
port = process.env.PORT || config.port,
|
||||
ready = (() => {
|
||||
var a = 'http://', b = config.listenip;
|
||||
if (config.ssl) a = 'https://';
|
||||
if (b == '0.0.0.0' || b == '127.0.0.1') b = 'localhost';
|
||||
console.log('AlloyProxy is now running at', a + b + ':' + port);
|
||||
});
|
||||
|
||||
// for compatibility with gatlin and other servers, export the app rather than passing it directly to http.createServer
|
||||
module.exports = app;
|
||||
http.globalAgent.maxSockets = Infinity;
|
||||
https.globalAgent.maxSockets = Infinity;
|
||||
|
||||
if (config.ssl) server = https.createServer(ssl, app).listen(port, config.listenip, ready);
|
||||
else server = http.createServer(app).listen(port, config.listenip, ready);
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(session({
|
||||
secret: 'alloy',
|
||||
saveUninitialized: true,
|
||||
resave: true
|
||||
}));
|
||||
|
||||
app.use((req, res, next)=>{
|
||||
// nice bodyparser alternative that wont cough up errors
|
||||
|
||||
req.setEncoding('utf8');
|
||||
req.raw_body = ''
|
||||
req.body = new Object()
|
||||
|
||||
req.on('data', chunk=>{ req.raw_body += chunk });
|
||||
|
||||
req.on('end', ()=>{
|
||||
req.str_body = req.raw_body.toString('utf8');
|
||||
|
||||
try{
|
||||
var result = new Object();
|
||||
|
||||
req.str_body.split('&').forEach((pair)=>{
|
||||
pair = pair.split('=');
|
||||
req.body[pair[0]] = decodeURIComponent(pair[1] || '');
|
||||
});
|
||||
}catch(err){
|
||||
req.body = {}
|
||||
}
|
||||
|
||||
return next();
|
||||
});
|
||||
});
|
||||
|
||||
function base64Encode(data) {
|
||||
return new Buffer.from(data).toString('base64')
|
||||
}
|
||||
|
||||
// How to use: base64Decode('string') will return any input base64 decoded
|
||||
function base64Decode(data) {
|
||||
return new Buffer.from(data, 'base64').toString('ascii')
|
||||
}
|
||||
|
||||
// How to use: rewritingURL('https://example.org/assets/main.js') will rewrite any external URL. Output: aHR0cHM6Ly9leGFtcGxlLm9yZw==/assets/main.js
|
||||
function rewriteURL(dataURL, option) {
|
||||
var websiteURL
|
||||
var websitePath
|
||||
if (option == 'decode') {
|
||||
websiteURL = base64Decode(dataURL.split('/').splice(0, 1).join('/'))
|
||||
websitePath = '/' + dataURL.split('/').splice(1).join('/')
|
||||
} else {
|
||||
websiteURL = base64Encode(dataURL.split('/').splice(0, 3).join('/'))
|
||||
websitePath = '/' + dataURL.split('/').splice(3).join('/')
|
||||
}
|
||||
if (websitePath == '/') {
|
||||
return `${websiteURL}`
|
||||
} else return `${websiteURL}${websitePath}`
|
||||
}
|
||||
|
||||
// To be used with res.send() to send error. Example: res.send(error('404', 'No valid directory or file was found!'))
|
||||
function error(statusCode, info) {
|
||||
if (statusCode && info) {
|
||||
return fs.readFileSync('alloy/assets/error.html', 'utf8').toString().replace('%ERROR%', `Error ${statusCode}: ${info}`)
|
||||
}
|
||||
if (info && !statusCode) {
|
||||
return fs.readFileSync('alloy/assets/error.html', 'utf8').toString().replace('%ERROR%', `Error: ${info}`)
|
||||
}
|
||||
if (statusCode && !info) {
|
||||
return fs.readFileSync('alloy/assets/error.html', 'utf8').toString().replace('%ERROR%', `Error ${statusCode}`)
|
||||
}
|
||||
return fs.readFileSync('public/assets/error.html', 'utf8').toString().replace('%ERROR%', `An error has occurred!`)
|
||||
}
|
||||
|
||||
app.post('/createSession', async (req, res) => {
|
||||
if (req.body.url.startsWith('//')) {
|
||||
req.body.url = 'http:' + req.body.url;
|
||||
} else if (req.body.url.startsWith('https://') || req.body.url.startsWith('http://')) {
|
||||
req.body.url = req.body.url;
|
||||
} else {
|
||||
req.body.url = 'http://' + req.body.url;
|
||||
}
|
||||
if (req.body.rv) {
|
||||
req.session.rvURL = String(req.body.url).split('/').splice(0, 3).join('/')
|
||||
return res.redirect('/fetch/rv/' + String(req.body.url).split('/').splice(3).join('/'))
|
||||
} else {
|
||||
return res.redirect('/fetch/' + rewriteURL(String(req.body.url)))
|
||||
}
|
||||
})
|
||||
|
||||
var prefix = '/fetch';
|
||||
|
||||
app.use(prefix, async (req, res, next) => {
|
||||
var location = rewriteURL(req.url.slice(1), 'decode');
|
||||
if (req.url.startsWith('/rv') && !req.session.rvURL) {
|
||||
res.send(error('400', 'No valid session URL for reverse proxy mode was found!'))
|
||||
}
|
||||
if (req.url.startsWith('/rv') && req.session.rvURL) {
|
||||
location = req.session.rvURL + req.url.slice(3)
|
||||
}
|
||||
location = {
|
||||
href: location,
|
||||
hostname : location.split('/').splice(2).splice(0, 1).join('/'),
|
||||
origin : location.split('/').splice(0, 3).join('/'),
|
||||
origin_encoded : base64Encode(location.split('/').splice(0, 3).join('/')),
|
||||
path : '/' + location.split('/').splice(3).join('/'),
|
||||
protocol : location.split('\:').splice(0, 1).join(''),
|
||||
}
|
||||
var httpAgent = new http.Agent({
|
||||
keepAlive: true
|
||||
});
|
||||
var httpsAgent = new https.Agent({
|
||||
keepAlive: true
|
||||
});
|
||||
|
||||
var fetchHeaders = req.headers
|
||||
fetchHeaders['referer'] = location.href
|
||||
fetchHeaders['origin'] = location.origin
|
||||
fetchHeaders['host'] = location.hostname
|
||||
if (fetchHeaders['cookie']) {
|
||||
delete fetchHeaders['cookie']
|
||||
}
|
||||
var options = {
|
||||
method: req.method,
|
||||
headers: fetchHeaders,
|
||||
redirect: 'manual',
|
||||
agent: function(_parsedURL) {
|
||||
if (_parsedURL.protocol == 'http:') {
|
||||
return httpAgent;
|
||||
} else {
|
||||
return httpsAgent;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (req.method == 'POST') {
|
||||
// Have to do try catch for this POST data parser until we create our own one that won't have a syntax error sometimes.
|
||||
try {
|
||||
// str_body is a string containing the requests body
|
||||
options['body'] = req.str_body;
|
||||
}catch(err){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (req.url.startsWith('/rv')) {
|
||||
location.origin_encoded = 'rv'
|
||||
}
|
||||
if (!req.url.startsWith(`/${location.origin_encoded}/`)) {
|
||||
try{
|
||||
return res.redirect(307,`/fetch/${location.origin_encoded}/`)
|
||||
}catch(err){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (location.href == 'https://discord.com' || location.href == 'https://discord.com/new') {
|
||||
return res.redirect(307, `/fetch/${location.origin_encoded}/login`)
|
||||
}
|
||||
if (location.origin == 'https://www.reddit.com') {
|
||||
if (req.url.startsWith('/rv') && req.session.rvURL) {
|
||||
req.session.rvURL = 'https://old.reddit.com'
|
||||
return res.redirect(307, '/fetch/rv' + location.path)
|
||||
}
|
||||
return res.redirect(307, '/fetch/' + base64Encode('https://old.reddit.com') + location.path)
|
||||
}
|
||||
const response = await fetch(location.href, options).catch(err => res.send(error('404', `"${location.href}" was not found!`)));
|
||||
if(typeof response.buffer != 'function')return;
|
||||
var resbody = await response.buffer();
|
||||
var contentType = 'text/plain'
|
||||
|
||||
response.headers.forEach((e, i, a) => {
|
||||
if (i == 'content-type') contentType = e;
|
||||
});
|
||||
if (contentType == null || typeof contentType == 'undefined') ct = 'text/html';
|
||||
var serverHeaders = Object.fromEntries(
|
||||
Object.entries(JSON.parse(JSON.stringify(response.headers.raw())))
|
||||
.map(([key, val]) => [key, val[0]])
|
||||
);
|
||||
if (serverHeaders['location']) {
|
||||
if (req.url.startsWith('/rv') && req.session.rvURL) {
|
||||
req.session.rvURL = String(serverHeaders['location']).split('/').splice(0, 3).join('/')
|
||||
return res.redirect(307, '/fetch/rv/' + String(serverHeaders['location']).split('/').splice(3).join('/'))
|
||||
} else return res.redirect(307, '/fetch/' + rewriteURL(String(serverHeaders['location'])))
|
||||
}
|
||||
delete serverHeaders['content-encoding']
|
||||
delete serverHeaders['x-frame-options']
|
||||
delete serverHeaders['strict-transport-security']
|
||||
delete serverHeaders['content-security-policy']
|
||||
delete serverHeaders['location']
|
||||
res.status(response.status)
|
||||
res.set(serverHeaders)
|
||||
res.contentType(contentType)
|
||||
if (response.redirected == true) {
|
||||
if (req.url.startsWith('/rv') && req.session.rvURL) {
|
||||
req.session.rvURL = response.url.split('/').splice(0, 3).join('/')
|
||||
return res.redirect(307, '/fetch/rv/' + response.url.split('/').splice(3).join('/'))
|
||||
} else return res.redirect(307, '/fetch/' + rewriteURL(response.url))
|
||||
}
|
||||
if (contentType.startsWith('text/html')) {
|
||||
req.session.fetchURL = location.origin_encoded
|
||||
resbody = resbody.toString()
|
||||
.replace(/integrity="(.*?)"/gi, '')
|
||||
.replace(/nonce="(.*?)"/gi, '')
|
||||
.replace(/(href|src|poster|data|action)="\/\/(.*?)"/gi, `$1` + `="http://` + `$2` + `"`)
|
||||
.replace(/(href|src|poster|data|action)='\/\/(.*?)'/gi, `$1` + `='http://` + `$2` + `'`)
|
||||
.replace(/(href|src|poster|data|action)="\/(.*?)"/gi, `$1` + `="/fetch/${location.origin_encoded}/` + `$2` + `"`)
|
||||
.replace(/(href|src|poster|data|action)='\/(.*?)'/gi, `$1` + `='/fetch/${location.origin_encoded}/` + `$2` + `'`)
|
||||
.replace(/'(https:\/\/|http:\/\/)(.*?)'/gi, function(str) {
|
||||
str = str.split(`'`).slice(1).slice(0, -1).join(``);
|
||||
return `'/fetch/${rewriteURL(str)}'`
|
||||
})
|
||||
.replace(/"(https:\/\/|http:\/\/)(.*?)"/gi, function(str) {
|
||||
str = str.split(`"`).slice(1).slice(0, -1).join(``);
|
||||
return `"/fetch/${rewriteURL(str)}"`
|
||||
})
|
||||
.replace(/(window|document).location.href/gi, `"${location.href}"`)
|
||||
.replace(/(window|document).location.hostname/gi, `"${location.hostname}"`)
|
||||
.replace(/(window|document).location.pathname/gi, `"${location.path}"`)
|
||||
.replace(/location.href/gi, `"${location.href}"`)
|
||||
.replace(/location.hostname/gi, `"${location.hostname}"`)
|
||||
.replace(/location.pathname/gi, `"${location.path}"`)
|
||||
.replace(/<html(.*?)>/gi, '<html' + '$1' + '><script id="alloyData" data-alloyURL="' + location.origin_encoded + '"' + ' src="/alloy/assets/inject.js"></script>')
|
||||
|
||||
} else if (contentType.startsWith('text/css')) {
|
||||
resbody = resbody.toString()
|
||||
.replace(/url\("\/\/(.*?)"\)/gi, `url("http://` + `$1` + `")`)
|
||||
.replace(/url\('\/\/(.*?)'\)/gi, `url('http://` + `$1` + `')`)
|
||||
.replace(/url\(\/\/(.*?)\)/gi, `url(http://` + `$1` + `)`)
|
||||
.replace(/url\("\/(.*?)"\)/gi, `url("/fetch/${location.origin_encoded}/` + `$1` + `")`)
|
||||
.replace(/url\('\/(.*?)'\)/gi, `url('/fetch/${location.origin_encoded}/` + `$1` + `')`)
|
||||
.replace(/url\(\/(.*?)\)/gi, `url(/fetch/${location.origin_encoded}/` + `$1` + `)`)
|
||||
.replace(/"(https:\/\/|http:\/\/)(.*?)"/gi, function(str) {
|
||||
str = str.split(`"`).slice(1).slice(0, -1).join(``);
|
||||
return `"/fetch/${rewriteURL(str)}"`
|
||||
})
|
||||
.replace(/'(https:\/\/|http:\/\/)(.*?)'/gi, function(str) {
|
||||
str = str.split(`'`).slice(1).slice(0, -1).join(``);
|
||||
return `'/fetch/${rewriteURL(str)}'`
|
||||
})
|
||||
.replace(/\((https:\/\/|http:\/\/)(.*?)\)/gi, function(str) {
|
||||
str = str.split(`(`).slice(1).join(``).split(')').slice(0, -1).join('');
|
||||
return `(/fetch/${rewriteURL(str)})`
|
||||
})
|
||||
|
||||
} else if (contentType.startsWith('text/javascript') || contentType.startsWith('application/javascript')) {
|
||||
resbody = resbody.toString()
|
||||
.replace(/xhttp.open\("GET",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhttp.open("GET",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true')
|
||||
.replace(/xhttp.open\("POST",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhttp.open("POST",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true')
|
||||
.replace(/xhttp.open\("OPTIONS",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhttp.open("OPTIONS",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true')
|
||||
|
||||
.replace(/xhr.open\("GET",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhr.open("GET",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true')
|
||||
.replace(/xhr.open\("POST",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhr.open("POST",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true')
|
||||
.replace(/xhr.open\("OPTIONS",(.*?)"http(.*?)"(.*?),(.*?)true\);/gi, ' xhr.open("OPTIONS",' + '$1' + '"/alloy/url/http' + '$2' + '"' + '$3' + ',' + '$4' + 'true')
|
||||
.replace(/ajax\("http:\/\/(.*?)"\)/gi, 'ajax("/alloy/url/http://' + '$1' + '")')
|
||||
.replace(/ajax\("https:\/\/(.*?)"\)/gi, 'ajax("/alloy/url/https://' + '$1' + '")')
|
||||
}
|
||||
res.send(resbody)
|
||||
})
|
||||
|
||||
app.use('/alloy/url/',function (req, res, next) {
|
||||
const mainurl = req.url.split('/').slice(1).join('/')
|
||||
const host = mainurl.split('/').slice(0, 3).join('/')
|
||||
const buff = new Buffer(host);
|
||||
const host64 = buff.toString('base64');
|
||||
const path = mainurl.split('/').slice(3).join('/')
|
||||
const fullURL = host64 + '/' + path
|
||||
res.redirect(307, '/fetch/' + fullURL)
|
||||
})
|
||||
|
||||
|
||||
app.use('/alloy/',function (req, res, next) {
|
||||
|
||||
if (req.query.url) {
|
||||
var clientInput = base64Decode(req.query.url)
|
||||
var fetchURL;
|
||||
if (clientInput.startsWith('//')) {
|
||||
fetchURL = rewriteURL('http:' + clientInput)
|
||||
} else if (clientInput.startsWith('http://') || clientInput.startsWith('https://')) {
|
||||
fetchURL = rewriteURL(clientInput)
|
||||
} else {
|
||||
fetchURL = rewriteURL('http://' + clientInput)
|
||||
}
|
||||
return res.redirect(307, '/fetch/' + fetchURL)
|
||||
}
|
||||
res.sendFile(__dirname + '/alloy' + req.url, function (err) {
|
||||
if (err) {
|
||||
if (req.session.fetchURL) {
|
||||
return res.redirect(307, '/fetch/' + req.session.fetchURL + req.url)
|
||||
} else return res.redirect(307, '/')
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
|
||||
app.use(express.static('public'))
|
||||
|
||||
app.use(function (req, res ,next) {
|
||||
if (req.session.fetchURL) {
|
||||
return res.redirect(307, '/fetch/' + req.session.fetchURL + req.url)
|
||||
} else return res.send(error('404', 'No valid directory or file was found!'))
|
||||
})
|
8
app.json
8
app.json
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"name": "Holy Unblocker",
|
||||
"description": "A website that can be used to bypass web filters; both online and firewall.",
|
||||
"repository": "https://github.com/QuiteAFancyEmerald/HolyUB"
|
||||
"name": "Alloy Proxy",
|
||||
"description": "A node.js web proxy featuring URL encoding, and amazing compatablity!",
|
||||
"repository": "https://github.com/titaniumnetwork-dev/alloyproxy/",
|
||||
"logo": "https://avatars1.githubusercontent.com/u/47227492?s=200&v=4",
|
||||
"keywords": ["node", "proxy", "unblocker"]
|
||||
}
|
5
config.json
Normal file
5
config.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"listenip":"0.0.0.0",
|
||||
"port":8080,
|
||||
"ssl":false
|
||||
}
|
24
newrelic.js
24
newrelic.js
|
@ -1,24 +0,0 @@
|
|||
/**
|
||||
* New Relic agent configuration.
|
||||
*
|
||||
* See lib/config.defaults.js in the agent distribution for a more complete
|
||||
* description of configuration variables and their potential values.
|
||||
*/
|
||||
exports.config = {
|
||||
/**
|
||||
* Array of application names.
|
||||
*/
|
||||
app_name: ['Node Unblocker'],
|
||||
/**
|
||||
* Your New Relic license key.
|
||||
*/
|
||||
license_key: process.env.NEW_RELIC_LICENSE_KEY,
|
||||
logging: {
|
||||
/**
|
||||
* Level at which to log. 'trace' is most useful to New Relic when diagnosing
|
||||
* issues with the agent, 'info' and higher will impose the least overhead on
|
||||
* production applications.
|
||||
*/
|
||||
level: 'info'
|
||||
}
|
||||
};
|
300
package-lock.json
generated
300
package-lock.json
generated
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "nodeunblocker.com",
|
||||
"name": "alloyproxy",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
|
@ -18,11 +18,6 @@
|
|||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"async": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
|
@ -63,6 +58,15 @@
|
|||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-parser": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
|
||||
"integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
|
||||
"requires": {
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6"
|
||||
}
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
|
@ -143,6 +147,33 @@
|
|||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"express-session": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
|
||||
"integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
|
||||
"requires": {
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~2.0.0",
|
||||
"on-headers": "~1.0.2",
|
||||
"parseurl": "~1.3.3",
|
||||
"safe-buffer": "5.2.0",
|
||||
"uid-safe": "~2.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
|
@ -157,6 +188,11 @@
|
|||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
|
||||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
|
@ -167,14 +203,6 @@
|
|||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"gatling": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gatling/-/gatling-1.2.0.tgz",
|
||||
"integrity": "sha1-rCDViqwTo82ntjtc0rO247MLEHw=",
|
||||
"requires": {
|
||||
"optimist": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
|
@ -205,11 +233,6 @@
|
|||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -243,11 +266,6 @@
|
|||
"mime-db": "1.44.0"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
|
@ -258,148 +276,10 @@
|
|||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"newrelic": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/newrelic/-/newrelic-1.40.0.tgz",
|
||||
"integrity": "sha1-JUjfFMRB6/ydO465idE397aaHW8=",
|
||||
"requires": {
|
||||
"concat-stream": "^1.5.0",
|
||||
"https-proxy-agent": "^0.3.5",
|
||||
"json-stringify-safe": "^5.0.0",
|
||||
"readable-stream": "^1.1.13",
|
||||
"semver": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"concat-stream": {
|
||||
"version": "1.6.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.2.11",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~1.0.6",
|
||||
"safe-buffer": "~5.0.1",
|
||||
"string_decoder": "~1.0.0",
|
||||
"util-deprecate": "~1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"bundled": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.0.1"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "0.3.6",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"agent-base": "~1.0.1",
|
||||
"debug": "2",
|
||||
"extend": "3"
|
||||
},
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.8",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.3.0",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
|
@ -409,14 +289,15 @@
|
|||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"optimist": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
||||
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
|
||||
"requires": {
|
||||
"minimist": "~0.0.1",
|
||||
"wordwrap": "~0.0.2"
|
||||
}
|
||||
"on-headers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
|
||||
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
|
||||
},
|
||||
"parse-raw-http": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-raw-http/-/parse-raw-http-0.0.1.tgz",
|
||||
"integrity": "sha512-GndQvIQXviId7eHnc+fEcmtEjkj1tQ96EhNOplPwXA8L1jgOnrlx/xLmmOEew8Yj4ZoZpmoAh0IvypAaeMbILg=="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
|
@ -442,6 +323,11 @@
|
|||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"random-bytes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
|
@ -506,11 +392,6 @@
|
|||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"set-cookie-parser": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.6.tgz",
|
||||
"integrity": "sha512-mNCnTUF0OYPwYzSHbdRdCfNNHqrne+HS5tS5xNb6yJbdP9wInV0q5xPLE0EyfV/Q3tImo3y/OXpD8Jn0Jtnjrg=="
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
|
@ -521,16 +402,6 @@
|
|||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"tld": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tld/-/tld-0.0.2.tgz",
|
||||
"integrity": "sha1-9g442CzaB14NzHlgHOXWgpzASd4="
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
|
@ -545,48 +416,12 @@
|
|||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"unblocker": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/unblocker/-/unblocker-2.0.5.tgz",
|
||||
"integrity": "sha512-dzt6dcfzC7W8MZ04nxsAKwF4uJBaYPLpZyab0pXdwTDVrJrxwU79PWO2ayxl9cavVAW4a7jJW7TSySDWibVmHA==",
|
||||
"uid-safe": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||
"requires": {
|
||||
"async": "^3.1.0",
|
||||
"content-type": "^1.0.4",
|
||||
"cookie": "^0.4.0",
|
||||
"debug": "^4.1.1",
|
||||
"iconv-lite": "^0.5.0",
|
||||
"lodash": "^4.17.15",
|
||||
"mime": "^2.4.4",
|
||||
"set-cookie-parser": "^2.4.1",
|
||||
"tld": "0.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz",
|
||||
"integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
|
||||
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
"random-bytes": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
|
@ -603,11 +438,6 @@
|
|||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
package.json
44
package.json
|
@ -1,22 +1,32 @@
|
|||
{
|
||||
"name": "nodeunblocker.com",
|
||||
"description": "Web proxy for evading internet censorship",
|
||||
"author": "Nathan Friedly - http://nfriedly.com",
|
||||
"name": "alloyproxy",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/nfriedly/nodeunblocker.com/",
|
||||
"dependencies": {
|
||||
"express": "^4.13.0",
|
||||
"gatling": "~1.2.0",
|
||||
"newrelic": "^1.20.2",
|
||||
"through": "^2.3.8",
|
||||
"unblocker": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"description": "A powerful web proxy!",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"start": "node ./node_modules/gatling/gatling.js ./app.js"
|
||||
"test": "proxy",
|
||||
"start": "node app.js"
|
||||
},
|
||||
"license": "AGPL-3.0"
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/titaniumnetwork-dev/alloyproxy.git"
|
||||
},
|
||||
"keywords": [
|
||||
"web-proxy"
|
||||
],
|
||||
"author": "titaniumnetwork-dev",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/titaniumnetwork-dev/alloyproxy/issues"
|
||||
},
|
||||
"homepage": "https://github.com/titaniumnetwork-dev/alloyproxy#readme",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.19.0",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.1",
|
||||
"follow-redirects": "^1.13.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"parse-raw-http": "0.0.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
var url = $('url').value;
|
||||
var det = document.domain;
|
||||
var domain = det.replace('www.', '').split(/[/?#]/)[0];
|
||||
window.location.href = "https://a." + domain + "/alloy?url=" + url;
|
||||
window.location.href = "https://" + domain + "/alloy?url=" + url;
|
||||
return false;
|
||||
};
|
||||
window.onload = function() {
|
||||
|
|
22
ssl/default.crt
Normal file
22
ssl/default.crt
Normal file
|
@ -0,0 +1,22 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDqzCCApOgAwIBAgIJAJnCkScWtmL0MA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRgwFgYDVQQKDA9UaXRhbml1bU5l
|
||||
dHdvcmsxDjAMBgNVBAsMBWdhbWVyMR4wHAYDVQQDDBUqLnRpdGFuaXVtbmV0d29y
|
||||
ay5vcmcwHhcNMjAwNjEzMTg0OTU2WhcNMjEwNjEzMTg0OTU2WjBsMQswCQYDVQQG
|
||||
EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEYMBYGA1UECgwPVGl0YW5pdW1OZXR3
|
||||
b3JrMQ4wDAYDVQQLDAVnYW1lcjEeMBwGA1UEAwwVKi50aXRhbml1bW5ldHdvcmsu
|
||||
b3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwPL69+RE6r8RrFh4
|
||||
njzC8ZRnLB+yNtuGw14C0dvNb5JwgdLl5g9/wK/s0V5NGlqwxlQlxQ/gUSuYEcUR
|
||||
6MYjcnaUmZZe/gaKVV0fkfkuigOWhLnI5AQxx7rhkzx1ujuyJ9D2pkDtZpSvv0yn
|
||||
2yrvWhJMtjuxGYip8jaLuRpbXoafvR7nrlDaNcE/GwIjnCCxsRnY2bGbxYK840mN
|
||||
fuMfF2nz+fXKPuQ/9PT48e3wOo9vM5s7yKhiHYwrogqzGN4cH4sSr1FE8C7flFyT
|
||||
Yw101u7fUaopfeGCo9Pg6IrfzyzE5Qb7OlqlVk2IkvXx7pPqVc6lZCJEhOX/qF9o
|
||||
n3mFqwIDAQABo1AwTjAdBgNVHQ4EFgQUC561ob2kGtFQ4az6y64b98+Fy+IwHwYD
|
||||
VR0jBBgwFoAUC561ob2kGtFQ4az6y64b98+Fy+IwDAYDVR0TBAUwAwEB/zANBgkq
|
||||
hkiG9w0BAQsFAAOCAQEAotvUsSLSzFyxQz329tEPyH6Tmi19FQoA5ZbLg6EqeTI9
|
||||
08qOByDGkSYJi0npaIlPO1I557NxRzdO0PxK3ybol6lnzuSlqCJP5nb1dr0z2Eax
|
||||
wgKht9P+ap/yozU5ye05ah2nkpcaeDPnwnnWFmfsnYNfgu62EshOS+5FETWEKVUb
|
||||
LXQhGInOdJq8KZvhoLZWJoUhyAqxBfW4oVvaqs+Ff96A2NNKrvbiAVYX30rVa+x0
|
||||
KIl0/DoVvDx2Q6TiL396cAXdKUW7edRQcSsGFcxwIrU5lePm0V05aN+oCoEBvXBG
|
||||
ArPN+a5kpGjJwfcpcBVf9cJ6IsvptGS9de3eTHoTyw==
|
||||
-----END CERTIFICATE-----
|
28
ssl/default.key
Normal file
28
ssl/default.key
Normal file
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDA8vr35ETqvxGs
|
||||
WHiePMLxlGcsH7I224bDXgLR281vknCB0uXmD3/Ar+zRXk0aWrDGVCXFD+BRK5gR
|
||||
xRHoxiNydpSZll7+BopVXR+R+S6KA5aEucjkBDHHuuGTPHW6O7In0PamQO1mlK+/
|
||||
TKfbKu9aEky2O7EZiKnyNou5Gltehp+9HueuUNo1wT8bAiOcILGxGdjZsZvFgrzj
|
||||
SY1+4x8XafP59co+5D/09Pjx7fA6j28zmzvIqGIdjCuiCrMY3hwfixKvUUTwLt+U
|
||||
XJNjDXTW7t9Rqil94YKj0+Doit/PLMTlBvs6WqVWTYiS9fHuk+pVzqVkIkSE5f+o
|
||||
X2ifeYWrAgMBAAECggEAbihK8Ev6rKr5RBQeiPjXs2SuoppV/MvIXLHHmliLKS/J
|
||||
29S0PGyM202VPtM/4dP1KMXR6nft8WmaIEsKtoKoqijZHfajtRO21pWb+JLy5wi1
|
||||
XoFTGBrs8MLZFl5mODTsuZ6rsq9O2kn5LJZvHsmcbSgVc9UQfytvG0HY840ArS3g
|
||||
kSDtUFb1xRui6wtCBKzHVvCT+FXhSBbwkHalmbqP6BefhJ3lW2VonkOcHDrdXPfW
|
||||
CEN18IJ2v8QYgXqZP6VUlAweNXLJ33ZOl+jXGdygcOG24MFqdw0VtP0XFGk0jnSS
|
||||
W6dX67BZKeZ71EKaTy02jw5LpQNXA70ismPJHQ2uQQKBgQDuROawnBIW1fC3xOle
|
||||
m+JmP0eMe0eIQycxRsMXsXhYAA0wV3qYZSLZrNK2eRhmSNt+ODSmZ2Vt11dwOv5u
|
||||
bo8WONrRlM097SmitS2S+8o7ASem2VKQzyRE72Y9517Q+aNBdLRVtjrRNSw/hfSu
|
||||
ayLuG36+yukSH7wq7mfoUX34ZwKBgQDPTrgyyw8n5XhZT/qTTRnQJ2GTvPxDzNoJ
|
||||
IAGhGJGFAb6wgLoSpGx6BC122vuRxcTjkjAiMDci5N2zNW+YZVni+F0KTVvNFfU2
|
||||
pOTJUg3luRTygCra6O02PxwpbP/9KCBAKq/kYw/eBW+gxhPwP3ZrbAirvBjgBh0I
|
||||
kIrFijNOHQKBgGUUAbFGZD4fwCCVflLOWnr5uUaVPcFGi6fR1w2EEgNy8iVh1vYz
|
||||
YVdqg3E5aepqWgLvoRY+or64LbXEsQ70A+tvbxSdxXvR0mnd5lmGS0JAuSuE4gvg
|
||||
dAhybrMwJf8NB/7KnX4G8mix3/WKxEQB2y2bqGcT+U/g+phTzuy1NXVdAoGBAIrl
|
||||
jVjK4J60iswcYCEteWwT1rbr2oF60WNnxG+xTF63apJLzWAMNnoSLnwCAKgMv/xR
|
||||
yFo/v9FrUnduCBUtYupFyeDLMATa/27bUEbq6VDPjw9jfFMr2TONWUsQMvvlVKZp
|
||||
c2wsS0dQkRhBXr6LZsZWngCiiHAg6HcCkVgFXpapAoGBAJ/8oLGt0Ar+0MTl+gyk
|
||||
xSqgHnsc5jgqhix3nIoI5oEAbfibdGmRD1S3rtWD9YsnPxMIl+6E5bOAHrmd+Zr8
|
||||
O7EP+CLvbz4JXidaaa85h9ThXSG5xk1A1UTtSFrp+KolLE1Vvmjjd+R844XsM2wZ
|
||||
OAHbihzk0iPPphjEWR4lU4Av
|
||||
-----END PRIVATE KEY-----
|
17
ssl/localhost.crt
Normal file
17
ssl/localhost.crt
Normal file
|
@ -0,0 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICwzCCAaugAwIBAgIJAMN1fA0fbQDSMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
|
||||
BAMTCWxvY2FsaG9zdDAeFw0yMDA2MDcyMDIyMDRaFw0zMDA2MDUyMDIyMDRaMBQx
|
||||
EjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBAPVHYq820Hi8Vy4ZAgmH/0Cl51TxWIWeoEgyQZEErgm1Vv49KuM0I1Ejk23+
|
||||
+tbKxY489dc7Gj/PqPv5F7SASNcxcKi5zbJPC6eEJBh2lHh6ldzF1aMfaYnuh25a
|
||||
3uhzoLpZPRsoTBysXkQZqC/6ZP6kBcwJnMZd12Uj4JIbdJwpyUorOYOv4GO6f7SA
|
||||
dUPUhSJpfUMZ4EFnkgrGJ18iqml/afhKj0g6KDxDGc1l2ioVMxiSjEfP06mbfkZ4
|
||||
zG16CmfITgyBFv8J9eF7exHCzqhbzgqWSfUNKazEKMbfCoegeZI196xtGIUbPYcf
|
||||
U8a5M+/pSmojMvdqsppqro0qwa0CAwEAAaMYMBYwFAYDVR0RBA0wC4IJbG9jYWxo
|
||||
b3N0MA0GCSqGSIb3DQEBBQUAA4IBAQBazEct+iiNe7/TY7c+l8wQBaCIhLtWxmfA
|
||||
JLGBu5Jt+HPAMskU5+rK0nWPMIW5le+xhHXXRnmjqH1pm157hR1LvanLoHpWsPTc
|
||||
eNx7utePC49t77UID1L2NHnmm9SAG/OhPJr3hh0AWG4GjJlWpK+9xeq7b9BoUsl7
|
||||
umU/X/02ZJmXWSwrqhspxtz3dSNaozAVVZs4Bokf7WiU27ACgffa7pCh9E8WTgyV
|
||||
jkvG5ZbmOeje7n+Fa0PEbTrm8SBtF/Rn96VkoZGJBC4+wia/0T5Gmjk8Ds9VhjVK
|
||||
bCyEsgPbkjwRdT/eRO4gEOgJI36CrheluWLnqjiidregyKYHQhwA
|
||||
-----END CERTIFICATE-----
|
27
ssl/localhost.key
Normal file
27
ssl/localhost.key
Normal file
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEA9UdirzbQeLxXLhkCCYf/QKXnVPFYhZ6gSDJBkQSuCbVW/j0q
|
||||
4zQjUSOTbf761srFjjz11zsaP8+o+/kXtIBI1zFwqLnNsk8Lp4QkGHaUeHqV3MXV
|
||||
ox9pie6Hblre6HOgulk9GyhMHKxeRBmoL/pk/qQFzAmcxl3XZSPgkht0nCnJSis5
|
||||
g6/gY7p/tIB1Q9SFIml9QxngQWeSCsYnXyKqaX9p+EqPSDooPEMZzWXaKhUzGJKM
|
||||
R8/TqZt+RnjMbXoKZ8hODIEW/wn14Xt7EcLOqFvOCpZJ9Q0prMQoxt8Kh6B5kjX3
|
||||
rG0YhRs9hx9Txrkz7+lKaiMy92qymmqujSrBrQIDAQABAoIBAQCQ6tFqlmdLvnN/
|
||||
3/StLvXn+12XeVUE9Xjbzx2gEfTF9adlZTxuqwJm0S8tISaRO5LHfEsAFIJoy0eb
|
||||
QEv6MIVY53QZrFXVERDgs5kj/wOvvzXGD/kufMO9Y/oOgJANJSwEje8lmYSGuGyl
|
||||
rccKOdXsAXsPV2qSZSV7M1xe1uvpyzpoUaX5aEfl44Kz1U6pURCpjqCj3OwVoaXa
|
||||
vlnDSI7LArhvVTR2Xifl9/MSz1qGlnlKTJTUJi5z+XEnIEqZmhYQOUnp2Wi4KWOR
|
||||
SqKnLOgfSJKb3yrdHukpLBsakF7U1urLB2wUjweZdn7zI9qbzIt9GIy1mRjYXTXL
|
||||
YwPDFOfBAoGBAP5Pi3+E8HV2L+6XOl9MYtKxn2KRvHQdR13IepmF+umhOxjfc6uC
|
||||
NhVeutfwuYfTXWmiEOHPKhH6NLloPbKkpfl6YxaKsAPfeEUI8PEA9J9TiNvGIP6m
|
||||
MZVsp5VS4Q/O2UTT9SG5dc3zOMmys1CJMIDZkzvub9HY1EiAiqRY/y+RAoGBAPbo
|
||||
e1yl/O2Z4L/ILaqo0QpIOgOdpWGZUIshUp5LEUzcYcflnCzdh1CYXWOAnPlvhh3H
|
||||
k4rTBMWJ4DaFWdNhYcOLowu0pk1Cm9q0akarmCr0DhKj98qubU/0QdzJ9q80eqYA
|
||||
3/pfFNs+baIGqcqOeD+da4ZrbLoefO7eBE1qJdpdAoGAFJjkt4NQ5nKYFz7wX1+U
|
||||
cXQpcJZVKSJl8VaXd2++jsWcP7t5Zt64+qodf/fjTvjzi+awb1mUEritJIco2Bs1
|
||||
xir/c4fwEaA74XuD6EEnju/5GbPGYFmdknimahW4XMtoFYcFR6H5xKB6bPuoQlGa
|
||||
OBVnM2dwbxKcvvKKSB1dLcECgYEAhQ4xdHMKwyv6Xr9MRLxmsijMAqjQt7C8I83Y
|
||||
TO9dKlNU6jlFGTRkOD1zjix/6zd7Sc8EJnqjBqTPS/I+vteqrIsyWRuHxvjPLmOt
|
||||
JdpQzUzpzIfJ/9JRnBWf7JB1vGMGeTDdgnn8rk2NHRSEKWDvUjDOAgkf9Yh6gOrp
|
||||
3KIINg0CgYEA5VURroq8FtoLUeiyueKwJ8pBeWVa1IOy9OyG7MaebYVcs5XqDyMk
|
||||
t/5dRHEbzjeM94qsi15BnwYtAy53RlIpA6VCsTxjgP53oj6emucoyj0eW4BRtTq1
|
||||
Er5OUU3Sl6JrILXmefjGTKha97boBWpUZQrJ/zgiqR4KvyGIBq4lqLo=
|
||||
-----END RSA PRIVATE KEY-----
|
Loading…
Add table
Add a link
Reference in a new issue