Commit e4bb679a authored by Artemis's avatar Artemis 🐱

Integrated new UI

parent 516c3313
......@@ -5,3 +5,4 @@ build/
node_modules/
# Configuration files, binaries etc.
paste*
build.css
@tailwind base;
@tailwind components;
@tailwind utilities;
select.h-full {
height: 40px;
}
h1:before {
content: '# ';
}
h2:before {
content: '## ';
}
......@@ -25,9 +25,10 @@ func (h Handlers) GetRouter() *vestigo.Router {
r.Get("/", h.HandleHome)
r.Post("/", h.HandleNewPaste)
r.Get("/about", h.HandleAbout)
r.Get("/s/:key", h.HandleShowPaste)
r.Get("/r/:key", h.HandleShowRaw)
r.Get("/privacy.html", h.HandlePrivacyPolicy)
r.Get("/static/*", h.HandleStaticContent)
return r
}
......@@ -36,6 +37,10 @@ func (h Handlers) HandleHome(w http.ResponseWriter, req *http.Request) {
_ = h.Templates.ExecuteTemplate(w, "homepage", nil)
}
func (h Handlers) HandleAbout(w http.ResponseWriter, req *http.Request) {
_ = h.Templates.ExecuteTemplate(w, "about", nil)
}
func (h Handlers) HandleNewPaste(w http.ResponseWriter, req *http.Request) {
err := req.ParseForm()
......@@ -143,6 +148,6 @@ func (h Handlers) HandleShowRaw(w http.ResponseWriter, req *http.Request) {
_, _ = fmt.Fprint(w, res.Val())
}
func (h Handlers) HandlePrivacyPolicy(w http.ResponseWriter, req *http.Request) {
_ = h.Templates.ExecuteTemplate(w, "privacy", nil)
func (h Handlers) HandleStaticContent(w http.ResponseWriter, req *http.Request) {
http.ServeFile(w, req, "./static/" + vestigo.Param(req, "_name"))
}
{
"name": "paste-prototype",
"version": "1.0.0",
"description": "New paste design",
"main": "index.js",
"author": "Artemis <[email protected]>",
"license": "Apache-2.0",
"private": true,
"dependencies": {
"uglifycss": "^0.0.29"
"cssnano": "^4.1.10",
"nodemon": "^1.19.1",
"postcss-cli": "^6.1.2",
"tailwindcss": "^1.0.4"
},
"scripts": {
"css-uglify": "uglifycss style.css > style.min.css"
"build": "postcss -o static/style.css css/style.css",
"watch": "nodemon css/style.css"
},
"nodemonConfig": {
"ignore": [
"build.css"
],
"execMap": {
"css": "yarn build",
"html": "yarn build"
}
},
"devDependencies": {
"@fullhuman/postcss-purgecss": "^1.2.0"
}
}
module.exports = {
theme: {
extend: {}
},
variants: {},
plugins: [
require('tailwindcss'),
require('autoprefixer'),
// require('@fullhuman/postcss-purgecss')({
// content: [
// './*.html'
// ],
// defaultExtractor: c => c.match(/[A-Za-z0-9-_:/]+/g) || []
// }),
require('cssnano')
]
};
body {
margin: 1em;
background-color: #F7F7F7;
color: #1E1E1E;
font-size: 1.2rem;
font-family: Sans-Serif;
}
p {
text-align: justify;
line-height: 1.4;
}
a {
color: #0677D3;
}
a:hover {
color: #9606D3;
}
footer {
text-align: center;
}
@media screen and (min-width: 1200px) {
body {
margin: 1em auto;
width: 1200px;
}
}
form fieldset {
padding: 0;
border: 0;
line-height: 2.8;
}
form fieldset label, form fieldset input, form fieldset textarea {
display: block;
width: 100%;
}
form fieldset textarea {
resize: vertical;
}
/*# sourceMappingURL=style.css.map */
package main
import "html/template"
import (
"fmt"
"html/template"
)
func lineCount(input string) uint {
var output uint = 0
for _, char := range input {
if char == '\n' {
output += 1
}
}
return output + 1 // final line, there's no line return
}
// Takes an input string, counts the number of lines,
// and generates an output with the same number of lines,
// each containing the line number.
func Lineno(input string) string {
count := lineCount(input)
output := ""
for i := uint(1); i < count; i++ {
output += fmt.Sprintf("%d\n", i)
}
return output[:len(output) - 1]
}
func InitTemplates() *template.Template {
return template.Must(template.ParseGlob("templates/*"))
return template.Must(template.New("").Funcs(template.FuncMap{
"lineno": Lineno,
}).ParseGlob("templates/*"))
}
{{define "about"}}
<!DOCTYPE html>
<html lang="en">
<head>
{{template "header"}}
</head>
<body class="bg-gray-900 text-white">
<header class="8 bg-gray-200 flex flex-wrap justify-between items-center p-2">
{{template "nav"}}
</header>
<main class="container mx-auto px-8 pb-8">
<h1 class="text-xl py-8">About paste</h1>
<p>
Paste is a FOSS ephemeral pastebin tool, made to be simple,
lightweight, and without any tracker or javascript.
</p>
<p>
Ephemeral means it does not store <i>anything</i> on a form of
persistent storage (like a HDD or a SSD), but instead only keeps
it in RAM for the selected duration (between 1 and 24 hours as of now).
</p>
<p>
FOSS means that the source-code is available for free for anyone
who might want to self-host it, or extend it
(<a href="#" class="underline text-blue-500 font-medium">Source-code</a>).
</p>
<h1 class="text-xl py-8">Privacy Policy</h1>
<p>
As general logging, we only collect your IP.
This is solely for cases where someone tries to abuse our services,
to be able to block them out.
</p>
<h2 class="text-lg py-6">Paste storing</h2>
<p>
Every paste is stored in ephemeral memory (RAM, through Redis configured
to not persist anything), with an auto-expiry set to, at maximum, 24 hours.
</p>
<p>
Following that, we don't persist anything, and once the expiry time
is passed, or the server (/ redis instance) rebooted, everything is
forgotten.
</p>
<h2 class="text-lg py-6">Analytics</h2>
<p>
Except for the possible exception above, we don't collect anything.
No, really. The person behind this is very privacy-conscious, so
they'll always try to only keep the necessary data, and <i>nothing more</i>.
No ad, no tracker in any form, period.
</p>
<h2 class="text-lg py-6">Security</h2>
<p>
We employ good methods to keep data secure. Not digging into details,
but the usual stuff, like a good firewall, monitoring system, and no
apparent openflow.
</p>
<p>
There's only one person who's technically authorized to be on the
hosting servers, so only one person should be able to have access.
</p>
<p>
Note that we're not saying that our servers and services are unbreakable
and perfect, but that we try to do our very best to prevent any
possibility for such incidents to occur.
</p>
<h2 class="text-lg py-6">Incident or vulnerability disclosure</h2>
<p>
If you managed to encounter an incident or a vulnerability in our
infrastructure, we'd gladly receive your feedback and alerts by
e-mail at <code>alert[at]artemix[dot]org</code>.
</p>
<p>
Responsible disclosure will allow us to recover and fix those
incidents without much risk, allowing us to provide you our services
with as much quality as we can manage to.
</p>
<p><i>Plus, you may receive a special mention or some small token of appreciation!</i></p>
</main>
</body>
</html>
{{end}}
{{define "footer"}}
<hr>
<footer>
<a href="https://gitlab.com/Artemix/paste" target="_blank">Source code</a>
| <a href="/privacy.html" target="_blank">Privacy Policy</a>
</footer>
{{end}}
{{define "header"}}
<meta charset="UTF-8">
<title>Paste</title>
<link rel="stylesheet" href="https://res.axdn.fr/paste/style.min.css" />
{{end}}
{{define "homepage"}}
<!DOCTYPE html>
<html lang="en">
<head>
<!DOCTYPE html>
<html lang="en">
<head>
{{template "header"}}
</head>
<body>
<h1>Paste</h1>
{{if .Error}}
<section>
<p><b>{{.Error}}</b></p>
</section>
{{end}}
<section>
<h2>Enter your document below (approximate maximum of 1MB)</h2>
<form method="post">
<fieldset>
<label for="paste">Your document</label>
<textarea name="paste" id="paste" rows="15" required autofocus>{{.Value}}</textarea>
</fieldset>
<fieldset>
<label for="time">Store duration</label>
<select name="time" id="time">
<option value="1h" selected>1 hour</option>
</head>
<body class="bg-gray-900 text-white h-screen">
<main class="flex flex-col h-screen">
<header class="8 bg-gray-200 flex flex-wrap justify-between items-center p-2">
{{template "nav"}}
<fieldset class="shadow-xl rounded bg-white text-black">
<select name="time" id="time" class="h-full p-2 rounded-l" form="paster">
<option value="1h">1 hour</option>
<option value="6h">6 hours</option>
<option value="12h">12 hours</option>
<option value="24h">1 day (24 hours)</option>
</select>
</fieldset>
<fieldset>
<button type="submit">Store</button>
<option value="24h" selected>1 day (24 hours)</option>
</select><button
type="submit"
form="paster"
class="p-2 bg-blue-400 text-white rounded-r">Store
</button>
</fieldset>
</header>
<form method="POST" id="paster" class="w-full flex-1">
<textarea
class="bg-gray-900 resize-none font-mono p-2 w-full h-full block"
name="paste"
id="paste"
rows="15"
required autofocus
placeholder="Enter your paste here"
spellcheck="false"></textarea>
</form>
<p>Pastes are stored for the selected duration (maximum of 24h) or until next server restart, whichever comes first.</p>
</section>
{{template "footer"}}
</body>
</html>
</main>
</body>
</html>
{{end}}
{{define "header"}}
<meta charset="UTF-8">
<title>Paste</title>
<link rel="stylesheet" href="/static/style.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
{{end}}
{{define "nav"}}
<nav class="text-black">
<a class="inline-block font-bold text-xl pr-2" href="/">Paste</a>
<a href="/about" class="underline text-blue-500 font-medium">About</a>
</nav>
{{end}}
{{define "privacy"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf8" />
<title>Privacy policy and incident report guidelines</title>
</head>
<body>
<h1>Privacy Notice</h1>
<p><i>Note that this Privacy Notice is a project-specific specialisation of the privacy policy linked <a href="https://res.axdn.fr/papers/privacy.html">here</a>.</i></p>
<h2>Paste storing</h2>
<p>Every paste is stored in RAM (through Redis, configured to not persist anything), with an auto-expiry set to either 1, 6, 12, or 24 hours.</p>
<p>In that sense, we don't persist anything, and once the expiry time is passed, or the server rebooted, everything is forgotten.</p>
</body>
</html>
{{end}}
{{define "show"}}
<!DOCTYPE html>
<html lang="en">
<head>
<!DOCTYPE html>
<html lang="en">
<head>
{{template "header"}}
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/monokai-sublime.min.css">
</head>
<body>
<h1>Paste</h1>
</head>
<body>
<header class="8 bg-gray-200 flex flex-wrap justify-between items-center p-2">
{{template "nav"}}
<fieldset class="shadow-xl rounded bg-white text-black">
<a
href="{{.Raw}}"
class="p-2 bg-blue-400 hover:bg-blue-800 text-white rounded">View raw</a>
</fieldset>
</header>
<nav>
<a href="/">Create a paste</a>
<a href="{{.Raw}}" target="_blank">Raw version</a>
</nav>
<main>
<pre class="flex">
<code class="border-r-2 border-gray-800">{{.Value|lineno}}</code>
<code class="flex-1">{{.Value}}</code>
</pre>
</main>
<section>
<h2>Your paste</h2>
<pre><code>{{.Value}}</code></pre>
</section>
{{template "footer"}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>
</body>
</html>
{{end}}
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
[email protected]^0.0.29:
version "0.0.29"
resolved "https://registry.yarnpkg.com/uglifycss/-/uglifycss-0.0.29.tgz#abe49531155d146e75dd2fdf933d371bc1180054"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment