setup paste ui

This commit is contained in:
Jon Lundy 2018-03-12 08:52:51 -06:00
parent 898bab21bf
commit 5692b739b2
26 changed files with 14678 additions and 934 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "assets/src/vendor/sour-is"]
path = assets/src/vendor/sour-is
url = git@git.dn42.us:xuu/souris-react.git
branch = master

21
assets/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

2434
assets/README.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,281 +0,0 @@
var app = angular.module('souris-app', ['souris-common', 'hljs']).
config(function ($routeProvider) {
$routeProvider.
when('/', {controller: CreateCtrl, templateUrl: 'ui/create.html'}).
when('/:id!:key', {controller: ViewCtrl, templateUrl: 'ui/view.html'}).
when('/:id', {controller: ViewCtrl, templateUrl: 'ui/view.html'}).
otherwise({redirectTo: '/'});
});
var TEXT = "";
function CreateCtrl($scope, $remoteService, $location, $route) {
"use strict";
$scope.reload = $route.reload;
$scope.o = {text: TEXT};
var base_url = window.location.origin;
$scope.$base_url = base_url;
// Add Randomness to RNG
console.info("Adding extra entropy from server and user input.");
$scope.entropy = 0;
var addEntropy = function (s) {
$scope.entropy += s.length;
fn.seed(s, {entropy: true});
};
$remoteService('/paste/rng').get().success(addEntropy);
(function (events, count) {
var t = [];
function w(e) {
t.push([e.pageX, e.pageY, e.keyCode, +new Date]);
if (t.length < count) {
return;
}
addEntropy(t);
$scope.$apply();
t = [];
}
for (var i in events)
if (events.hasOwnProperty(i))
document.addEventListener(events[i], w);
})(['mousemove', 'keydown', 'keypress', 'click', 'scroll'], 16);
$scope.HighliteLang = fn.obj(HighliteLang);
$scope.ExpireTimes = fn.obj(ExpireTimes);
// Encrypt and send function
$scope.Encrypt = function (o) {
if (o.text.length > 512) {o.zip = true; $scope.o.zip = true; }
var e = encrypt(o);
console.log("Sending:\n" + e.txt);
$remoteService('/paste')
.post({}, e.txt)
.success(function (d) {
console.log("Received:\n" + d);
d = d.split(' ');
$scope.result = {status: d[0], id: d[1], key: e.key, text: e.txt};
});
};
}
CreateCtrl.$inject = ['$scope', '$remoteService', '$location', '$route'];
function ViewCtrl($scope, $params, $remoteService, $location) {
"use strict";
var base_url = window.location.origin;
$scope.$base_url = base_url;
var id = $params.id,
key = $params.key;
$scope.id = id;
$scope.key = key;
function store(o) {
$scope.store = o;
}
$scope.copy = function(t) {
TEXT = t;
$location.path('/');
};
$remoteService('/paste/:id')
.get({id: id})
.success(decrypt(key, store))
.error(function(d, c){
var msg = '';
switch(c){
case 403: msg = 'Authentication Required.'; break;
case 404: msg = 'Message Not Found.'; break;
case 410: msg = 'Message Expired.'; break;
}
$scope.store = {err:msg, code:c};
});
}
ViewCtrl.$inject = ['$scope', '$routeParams', '$remoteService', '$location'];
var HighliteLang = [["text", "Plain Text"], ["apache", "Apache"], ["bash", "Bash"], ["coffeescript", "CoffeeScript"], ["cpp", "C++"], ["cs", "C#"], ["css", "CSS"], ["diff", "Diff"], ["http", "HTTP"], ["ini", "Ini"], ["java", "Java"], ["javascript", "JavaScript"], ["json", "JSON"], ["makefile", "Makefile"], ["markdown", "Markdown"], ["nginx", "Nginx"], ["objectivec", "Objective C"], ["perl", "Perl"], ["php", "PHP"], ["python", "Python"], ["ruby", "Ruby"], ["sql", "SQL"], ["xml", "HTML, XML"]];
var ExpireTimes = [[3600, "1 Hour"], [86400, "1 Day"], [604800, "1 Week"], [2419200, "4 Weeks"], [15778463, "6 Months"], [31556926, "1 Year"]];
var fn = {
sha: function (s) { return this.b64(CryptoJS.SHA256(s)); },
rmd: function (s) { return this.b64(CryptoJS.RIPEMD160(s)); },
chk: function (s) { return this.b64(CryptoJS.RIPEMD160(CryptoJS.SHA256(s))); },
enc: function (t, p) { return CryptoJS.AES.encrypt(t, p).toString(); },
dec: function (c, p) { return CryptoJS.AES.decrypt(c, p); },
b64: function (s) {
if (s === undefined) return;
return CryptoJS.enc.Base64.stringify(s).replace(/[=]+/, '').replace(/\//g, '_').replace(/\+/g, '-');
},
d64: function (s) {
if (s === undefined) return;
switch (s.length % 3) {
case 2:
s += '=';
// fallthrough
case 1:
s += '=';
}
return CryptoJS.enc.Base64.parse(s.replace(/_/g, '/').replace(/-/g, '+'));
},
rng: function (n) { return this.b64(CryptoJS.lib.WordArray.random(n)); },
seed: Math.seedrandom,
u8a: function (wa) {
var w = wa.words;
var b = new Uint8Array(w.length * 4), v, i, j, k = 0;
for (i = 0; i < w.length; ++i) {
v = w[i];
for (j = 3; j >= 0; --j) {
b[k++] = ((v >> 8 * j) & 0xFF);
}
}
return b;
},
u16a: function (ua) {
var s = '';
for (var i = 0; i < ua.length; i++) {
s += ('0' + ua[i].toString(16)).slice(-2);
}
return CryptoJS.enc.Hex.parse(s);
},
str8: function (ua) {
var s = '';
for (var i = 0; i < ua.byteLength; i++) {
if ((ua[i]&0x80) === 0) s += String.fromCharCode(ua[i]);
else if ((ua[i]&0xe0) === 0xc0 && (ua[i+1]&0xc0) === 0x80) {
s += String.fromCharCode(((ua[i]&0x1f)<<6) + (ua[i+1]&0x3f));
i += 1;
}
else if ((ua[i]&0xf0) === 0xe0 && (ua[i+1]&0xc0) === 0x80 && (ua[i+2]&0xc0) === 0x80){
s += String.fromCharCode(((ua[i]&0x0f)<<12) + ((ua[i+1]&0x3f)<<6) + (ua[i+2]&0x3f));
i += 2;
}
else if ((ua[i]&0xf8) === 0xf0 && (ua[i+1]&0xc0) === 0x80 && (ua[i+2]&0xc0) === 0x80 && (ua[i+3]&0xc0) === 0x80) {
s += String.fromCharCode(((ua[i]&0x0f)<<18) + ((ua[i+1]&0x3f)<<12) + ((ua[i+2]&0x3f)<<6) + (ua[i+3]&0x3f));
i += 3;
}
else { s += String.fromCharCode(65533); }
}
return s;
},
obj: function (a) {
var o = [];
for (var i = 0; i < a.length; i++) {
o.push({key: a[i][0], val: a[i][1]});
}
return o;
}
};
var decrypt = function (key, tgt) {
return function (d) {
if (d.length === 0) tgt({err: "Not Found", code: 'not_found'});
var s = d.split('\n');
d = {};
var i = 0;
while (true) {
if (s[i] === "") break;
var l = s[i].trim().split(':\t');
d[l[0]] = l[1];
i++;
}
d.tx = s.splice(i).join('');
if (key === undefined) tgt({err: "Missing Key", code: 'no_key'});
else if (d.chk !== fn.rmd(fn.d64(key))) tgt({err: "Invalid Key", code: "bad_key"});
else {
var tx;
if (d.zip) {
tx = fn.dec(d.tx, key);
tx = fn.u8a(tx);
tx = fn.str8(pako.inflate(tx));
} else {
tx = fn.dec(d.tx, key).toString(CryptoJS.enc.Utf8);
}
var lang = 'text';
for (i = 0; i < HighliteLang.length; i++)
if (d.lang === HighliteLang[i][0])
lang = HighliteLang[i][0];
tgt({code: 'ok', tx: tx, lang: lang, exp: d.exp, zip: d.zip});
}
};
};
var encrypt = function (o) {
var ts = Date.now();
console.info("Begin Encryption Process...");
var pass;
if (o.pass !== undefined) pass = fn.chk(o.pass);
var r = fn.rng(40);
var key = fn.sha(r);
var chk = fn.chk(r);
var text = o.text;
if (o.zip) {
console.info("Compressing text...");
var bl = o.text.length, bs = Date.now();
var deflate = pako.gzip(text);
text = fn.u16a(deflate);
console.info("Compress complete: " + (Date.now() - bs) + "ms, " + bl + " => " + o.text.length + " bytes");
}
var enc = fn.enc(text, key);
var exp = (o.exp === undefined ? undefined : (o.exp + Date.now() / 1000 | 0));
var header = {
'pass': pass,
'chk': chk,
'lang': o.lang,
'exp': exp,
'zip': o.zip,
'burn': o.burn
};
var s = '';
for (var i in header) if (header.hasOwnProperty(i)) if (header[i] !== undefined) {
s += i + ":\t" + header[i] + "\n";
}
s += "\n";
while (enc.length > 79) {
s += enc.slice(0, 79) + "\n";
enc = enc.slice(79);
}
s += enc + "\n";
console.info("Encrypt complete: " + (Date.now() - ts) + " ms");
return {'txt': s, 'key': key};
};
m.filter('blength', function () {
return function (o) {
if (!(typeof o === 'string' || o instanceof String)) return;
if (o === undefined || o.length === undefined) return;
var utf8length = 0;
for (var n = 0; n < o.length; n++) {
var c = o.charCodeAt(n);
if (c < 128) {
utf8length++;
}
else if ((c > 127) && (c < 2048)) {
utf8length = utf8length + 2;
} else {
utf8length = utf8length + 3;
}
}
return utf8length;
};
});

File diff suppressed because one or more lines are too long

View File

@ -1,3 +0,0 @@
/* highlight.js 8.4 */
.hljs{display:block;overflow-x:auto;padding:0.5em;background:#f0f0f0;-webkit-text-size-adjust:none}.hljs,.hljs-subst,.hljs-tag .hljs-title,.nginx .hljs-title{color:black}.hljs-string,.hljs-title,.hljs-constant,.hljs-parent,.hljs-tag .hljs-value,.hljs-rules .hljs-value,.hljs-preprocessor,.hljs-pragma,.haml .hljs-symbol,.ruby .hljs-symbol,.ruby .hljs-symbol .hljs-string,.hljs-template_tag,.django .hljs-variable,.smalltalk .hljs-class,.hljs-addition,.hljs-flow,.hljs-stream,.bash .hljs-variable,.apache .hljs-tag,.apache .hljs-cbracket,.tex .hljs-command,.tex .hljs-special,.erlang_repl .hljs-function_or_atom,.asciidoc .hljs-header,.markdown .hljs-header,.coffeescript .hljs-attribute{color:#800}.smartquote,.hljs-comment,.hljs-annotation,.diff .hljs-header,.hljs-chunk,.asciidoc .hljs-blockquote,.markdown .hljs-blockquote{color:#888}.hljs-number,.hljs-date,.hljs-regexp,.hljs-literal,.hljs-hexcolor,.smalltalk .hljs-symbol,.smalltalk .hljs-char,.go .hljs-constant,.hljs-change,.lasso .hljs-variable,.makefile .hljs-variable,.asciidoc .hljs-bullet,.markdown .hljs-bullet,.asciidoc .hljs-link_url,.markdown .hljs-link_url{color:#080}.hljs-label,.hljs-javadoc,.ruby .hljs-string,.hljs-decorator,.hljs-filter .hljs-argument,.hljs-localvars,.hljs-array,.hljs-attr_selector,.hljs-important,.hljs-pseudo,.hljs-pi,.haml .hljs-bullet,.hljs-doctype,.hljs-deletion,.hljs-envvar,.hljs-shebang,.apache .hljs-sqbracket,.nginx .hljs-built_in,.tex .hljs-formula,.erlang_repl .hljs-reserved,.hljs-prompt,.asciidoc .hljs-link_label,.markdown .hljs-link_label,.vhdl .hljs-attribute,.clojure .hljs-attribute,.asciidoc .hljs-attribute,.lasso .hljs-attribute,.coffeescript .hljs-property,.hljs-phony{color:#88f}.hljs-keyword,.hljs-id,.hljs-title,.hljs-built_in,.css .hljs-tag,.hljs-javadoctag,.hljs-phpdoc,.hljs-dartdoc,.hljs-yardoctag,.smalltalk .hljs-class,.hljs-winutils,.bash .hljs-variable,.apache .hljs-tag,.hljs-type,.hljs-typename,.tex .hljs-command,.asciidoc .hljs-strong,.markdown .hljs-strong,.hljs-request,.hljs-status{font-weight:bold}.asciidoc .hljs-emphasis,.markdown .hljs-emphasis{font-style:italic}.nginx .hljs-built_in{font-weight:normal}.coffeescript .javascript,.javascript .xml,.lasso .markup,.tex .hljs-formula,.xml .javascript,.xml .vbscript,.xml .css,.xml .hljs-cdata{opacity:0.5}
.hljs{display:block;overflow-x:auto;padding:0.5em;background:#ffffff}.hljs,.hljs-subst{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-built_in,.hljs-literal,.hljs-bullet,.hljs-code,.hljs-addition{color:#1F811F}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-comment{color:#888888}.hljs-meta{color:#2B6EA1}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}

View File

@ -1,63 +0,0 @@
<?doctype html?>
<html ng-app='souris-app'>
<head>
<base href="/" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PasteBox</title>
<!--INSERT_TEMPLATES-->
</head>
<body>
<div id="wrapper">
<div class="container-responsive">
<article ng-view></article>
<a onclick='var elm = document.getElementById("debug"); elm.parentNode.style.display="block"; window.scrollTop = window.scrollHeight;' style="margin:3px;cursor:context-menu;font-family:monospace;position:fixed;bottom:0;right:0">&pi;</a>
<div class='panel panel-default' style='height:13em;margin-bottom:0;margin-top:2em;;display:none;position:relative;bottom:0'><b>Debug Log</b>
<div style='float:right'>
<a class="btn" onclick='document.getElementById("debug").parentNode.style.display="none";'><i class='glyphicon glyphicon-remove'></i></a><br/>
<a class="btn" onclick='var elm=document.getElementById("debug");while (elm.firstChild) {elm.removeChild(elm.firstChild);}'><i class='glyphicon glyphicon-ban-circle'></i></a>
</div>
<pre id=debug style='height:12em; overflow:scroll;'></pre>
<footer></footer></div>
</div>
</div>
<!--REMOVE_ASSET_START-->
<link rel="stylesheet" href="bootstrap.min.css">
<link rel="stylesheet" href="highlightjs.min.css">
<script src='lib.js'></script>
<!--REMOVE_ASSET_END-->
<link rel="stylesheet" href="style.css" />
<script src='app.js'></script>
<noscript>
<div class=container-responsive>
<h1>PasteBox</h1>
<p>It looks like yo don't have javascript enabled for this site. But thats ok. You can still submit and read the content of pastes by using a few curl/openssl/gunzip commands.</p>
<h2>Get the paste</h2>
<p>Lets say you have the following link <code>https://domain.tld/#/FeLq42kIQV69hQCJA8m9lg!5EDDziaCjceHjeG5UQ9M7-6wgyq5YVfysAEZ0wUNy6w</code>. Query the REST endpoint for the ID or part before the ! in the url hash.</p>
<pre><code>$ curl -i https://domain.tld/api/FeLq42kIQV69hQCJA8m9lg</code></pre>
<h2>Decrypt</h2>
<p>Using Openssl you want to remove the header and pass the remaining base64 for decryption. The cypher used is aes-256-cbc. The key is the portion after the ! in the link.</p>
<pre><code>... | sed '1,/^$/d' | openssl aes-256-cbc -d -a -k 5EDDziaCjceHjeG5UQ9M7-6wgyq5YVfysAEZ0wUNy6w</code></pre>
<h2>Deflate</h2>
<p>If as in the provided example the paste has been compressed pass it through gunzip. The header will have "zip: true" if it has been compressed.</p>
<pre><code> ... | gzip -dc </code></pre>
<h2>Example Output</h2>
<pre><code>$ curl -s "https://domain.tld/api/FeLq42kIQV69hQCJA8m9lg" | sed "1,/^$/d" | openssl aes-256-cbc -d -a -k 5EDDziaCjceHjeG5UQ9M7-6wgyq5YVfysAEZ0wUNy6w | gzip -dc
. ____ .-.
.-"` `",( __\_
.-==:;-._ .' .-. `'.
.' `"-:'-/ ( \} -=a .)
/ \/ \,== `- __..-'`
'-' | | | .'\ `;
\ _/---'\ ( `"`
/.`._ ) \ `; Sour.is Paste
\`-/.' `"`
`"\`-.</code></pre>
</div>
</noscript>
</body>
</html>

File diff suppressed because one or more lines are too long

11943
assets/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
assets/package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "paste",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1",
"sour-is": "git+ssh://git@git.dn42.us:xuu/souris-react.git"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}

View File

@ -1,45 +0,0 @@
#!/bin/bash
if [ "$1" = "-h" ]; then
cat 1>&2 <<EOL
usage: echo /etc/passwd | ./paste.sh
env options:
PASTE_URL - Set the url base for paste operations (default: HTTPS://paste.dn42.us)
PASTE_GZIP - 0 = No Compression, 1 = Use gzip compression (default: 0)
PASTE_BURN - 0 = No Burn on Read, 1 = Burn on read (default: 0)
PASTE_DATE - Value to be used when setting expire date. (default: next-week)
EOL
exit
fi
PASTE_URL=${PASTE_URL-"https://paste.dn42.us"}
PASTE_BURN=${PASTE_BURN-0}
PASTE_DATE=${PASTE_DATE-"next-week"}
PASTE_GZIP=${PASTE_GZIP-0}
GZBIN="cat"
[ "$PASTE_GZIP" -eq "1" ] && GZBIN="gzip -c"
PASS=$(head -c 40 /dev/urandom);
CHK=$(echo -s $PASS | openssl dgst -sha256 -binary | openssl dgst -ripemd160 -binary | base64 | tr '/+' '_-' | tr -d '=')
PASS=$(echo -s $PASS | openssl dgst -sha256 -binary | base64 | tr '/+' '_-' | tr -d '=')
HASH=$((echo -e "exp:\t$(date +%s -d ${PASTE_DATE})"; \
echo -e "chk:\t$CHK"; \
[ "$PASTE_BURN" -eq "1" ] && echo -e "burn:\ttrue"; \
[ "$PASTE_GZIP" -eq "1" ] && echo -e "zip:\ttrue"; \
echo; \
cat /dev/stdin | $GZBIN | openssl aes-256-cbc -e -a -k $PASS) | \
curl -s -X POST ${PASTE_URL}/paste --data-binary @-)
HASH_OK=$(echo $HASH | cut -c1-2)
if [ "$HASH_OK" = "OK" ]; then
HASH=$(echo $HASH | cut -f2 -d' ')
echo "url: ${PASTE_URL}/#/${HASH}!${PASS}"
echo -n "shell: curl -s ${PASTE_URL}/api/get/${HASH} | sed '1,/^\$/d' | openssl aes-256-cbc -d -a -k ${PASS}"
[ "$PASTE_GZIP" -eq "1" ] && echo " | gzip -dc" || echo;
exit
fi
echo $HASH

BIN
assets/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

20
assets/public/index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>DN42 Paste</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,15 @@
{
"short_name": "DN42 Paste",
"name": "Paste tool for DN42",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#000000"
}

28
assets/src/App.css Normal file
View File

@ -0,0 +1,28 @@
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
.App-title {
font-size: 1.5em;
}
.App-intro {
font-size: large;
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

49
assets/src/App.js Normal file
View File

@ -0,0 +1,49 @@
import React, { Component } from 'react';
import Paste from './vendor/src/paste/Paste';
import Framework from './vendor/src/sour-is/Framework';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { remoteService } from "./vendor/src/sour-is/RemoteService";
const req = remoteService();
const APP_NAME = "DN42 Paste UI";
class App extends Component {
constructor(){
super()
this.state = {
name: APP_NAME,
api: "Paste API (Version Snapshot)"
}
}
componentDidMount() {
req('/app-info').get()
.then((response) => {
if (response.ok) return response.text().catch(()=>"");
else return "Unknown API"; })
.then((text) => { this.setState({app:{name: APP_NAME, api: text}}); });
}
render() {
const {api, name} = this.state;
return (
<BrowserRouter>
<React.Fragment key={1}>
<section className="container-responsive">
<Switch>
<Route path="/" component={Paste} />
</Switch>
</section>
<footer>
<span className="left text-muted">{name}</span>
<span className="right text-muted">{api}</span>
</footer>
</React.Fragment>
</BrowserRouter>
);
}
}
export default App;

9
assets/src/App.test.js Normal file
View File

@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

5
assets/src/index.css Normal file
View File

@ -0,0 +1,5 @@
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}

8
assets/src/index.js Normal file
View File

@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

7
assets/src/logo.svg Normal file
View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,117 @@
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://goo.gl/SC7cgQ'
);
});
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

1
assets/src/vendor/sour-is vendored Submodule

@ -0,0 +1 @@
Subproject commit 3ca08bd7a65e967bb4e95969ba59130f25287331

View File

@ -1 +0,0 @@
body {background:#eee;}pre {padding:0}pre,pre code {font-family:hack,"Anonymous Pro",consolitas,monospace}.well {margin-bottom:0;}

View File

@ -1 +0,0 @@
Test.

View File

@ -1,56 +0,0 @@
<div class=row ng-show='result != undefined'>
<div class=col-xs-12>
<div class="input-group">
<span class="input-group-btn">
<a class="btn btn-default" ng-click='reload()' type="button">New</a>
</span>
<input type=text readonly class=form-control select-on-click value="{{$base_url}}/#/{{result.id}}!{{result.key}}">
<span class="input-group-btn">
<a class='btn btn-default' ng-href='/#/{{result.id}}!{{result.key}}'>Open</a>
</span>
</div>
</div>
<pre class=col-xs-12> # Command Line: curl -s {{$base_url}}/api/get/{{result.id}} | sed "1,/^\$/d" | openssl aes-256-cbc -d -a -k {{result.key}} <span ng-if='o.zip == true'>| gzip -dc</span>
{{result.text}}</pre>
</div>
<div ng-hide='result != undefined'>
<form name=paste ng-submit='Encrypt(o)'>
<div class="form form-inline">
<ol class='breadcrumb'>
<li>
<label>Syntax</label>
<select class='form-control input-sm' ng-model=o.lang ng-options='i.key as i.val for i in HighliteLang | orderBy:"+val"' ng-init='o.lang = "text"'></select>
</li>
<li>
<label>Expires</label>
<select class='form-control input-sm' ng-model=o.exp ng-options='i.key as i.val for i in ExpireTimes | orderBy:"+key"' ng-init='o.exp = 604800'></select>
</li>
<li>
<label><input type=checkbox ng-model='o.burn' /> Burn on Read</label>
</li>
</ol>
</div>
<textarea style='font-family: hack,"Anonymous Pro",consolita,monospace' required class='form-control' rows=20 ng-model="o.text"></textarea>
<pre>Additional Entropy: {{entropy}} bytes / Content size: {{o.text|blength|default:0}} bytes</pre>
<button type=submit class='btn btn-default btn-lg btn-block' ng-disabled="o.text == undefined || o.text.length == 0">Encrypt</button>
</form>
<p>Create pastes from the command line! <a href=./paste.sh>paste.sh</a>
<pre>
$ echo /etc/passwd | ./paste.sh
env options:
PASTE_URL - Set the url base for paste operations (default: HTTPS://paste.dn42.us)
PASTE_GZIP - 0 = No Compression, 1 = Use gzip compression (default: 0)
PASTE_BURN - 0 = No Burn on Read, 1 = Burn on read (default: 0)
PASTE_DATE - Value to be used when setting expire date. (default: next-week)
</pre>
</p>
</div>

View File

@ -1,21 +0,0 @@
<div class=row>
<div class=col-xs-12>
<div class="input-group">
<span class="input-group-btn">
<a class="btn btn-default" ng-href='/#/' type="button">New</a>
</span>
<input type=text readonly class=form-control select-on-click value="{{$base_url}}/#/{{id}}!{{key}}">
<span class="input-group-btn">
<a class='btn btn-default' ng-click='copy(store.tx)'>Copy</a>
</span>
</div>
</div>
</div>
<div ng-if="store.err == undefined">
<div class='well well-sm'>
<b>Lang:</b> {{store.lang}}, <b>Expires:</b> <span ng-if='store.exp != "burn_on_read"'>{{store.exp*1000|date}}</span><span ng-if='store.exp == "burn_on_read"'>Burn on Read</span>
</div>
<div hljs language="{{store.lang}}" source="store.tx"></div>
<pre class=col-xs-12> # Command Line: curl -s {{$base_url}}/api/get/{{id}} | sed "1,/^\$/d" | openssl aes-256-cbc -d -a -k {{key}} <span ng-if='store.zip != undefined'>| gzip -dc</span>
</div>
<div ng-if="store.err != undefined"><h3>Error: {{store.err}}</h3></div>