Compare commits

..

No commits in common. "83b4f5fe041d11caca936b12ad1ca5540dfc3f19" and "6567a7c0cd3fbe3f28da8a383dfe2bce4b983c1b" have entirely different histories.

11 changed files with 118 additions and 134 deletions

6
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/plakken.iml" filepath="$PROJECT_DIR$/.idea/plakken.iml" />
</modules>
</component>
</project>

10
.idea/plakken.iml Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="highlight.js" level="application" />
</component>
</module>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -7,7 +7,7 @@ import (
"strconv"
)
type Config struct {
type config struct {
host string
port string
redisAddr string
@ -17,7 +17,7 @@ type Config struct {
urlLength int
}
func GetConfig() Config {
func getConfig() config {
err := godotenv.Load()
if err != nil {
log.Fatalf("Error loading .env file: %v", err)
@ -42,7 +42,7 @@ func GetConfig() Config {
log.Fatal("Invalid PLAKKEN_REDIS_URL_LEN")
}
return Config{
conf := config{
host: os.Getenv("PLAKKEN_INTERFACE"),
port: port,
redisAddr: redisAddr,
@ -51,4 +51,6 @@ func GetConfig() Config {
redisDB: redisDB,
urlLength: urlLen,
}
return conf
}

5
db.go
View file

@ -9,7 +9,7 @@ import (
var ctx = context.Background()
func ConnectDB() *redis.Client {
func connectDB() *redis.Client {
localDb := redis.NewClient(&redis.Options{
Addr: currentConfig.redisAddr,
Username: currentConfig.redisUser,
@ -40,7 +40,8 @@ func insertPaste(key string, content string, secret string, ttl time.Duration) {
}
func getContent(key string) string {
return db.HGet(ctx, key, "content").Val()
content := db.HGet(ctx, key, "content").Val()
return content
}
func deleteContent(key string) {

31
main.go
View file

@ -10,7 +10,7 @@ import (
"strings"
)
var currentConfig Config
var currentConfig config
var db *redis.Client
type pasteView struct {
@ -21,17 +21,16 @@ type pasteView struct {
func handleRequest(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
clearPath := strings.ReplaceAll(r.URL.Path, "/raw", "")
staticResource := "/static/"
switch r.Method {
case "GET":
if path == "/" {
http.ServeFile(w, r, "./static/index.html")
} else if strings.HasPrefix(path, staticResource) {
} else if strings.HasPrefix(path, "/static/") {
fs := http.FileServer(http.Dir("./static"))
http.Handle(staticResource, http.StripPrefix(staticResource, fs))
http.Handle("/static/", http.StripPrefix("/static/", fs))
} else {
if UrlExist(clearPath) {
if urlExist(clearPath) {
if strings.HasSuffix(path, "/raw") {
pasteContent := getContent(clearPath)
w.Header().Set("Content-Type", "text/plain")
@ -57,8 +56,8 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
}
case "POST":
if path == "/" {
secret := GenerateSecret()
url := "/" + GenerateUrl()
secret := generateSecret()
url := "/" + generateUrl()
content := r.FormValue("content")
insertPaste(url, content, secret, -1)
http.Redirect(w, r, url, http.StatusSeeOther)
@ -66,13 +65,12 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
}
case "DELETE":
if UrlExist(path) {
if strings.HasPrefix(path, "/delete") {
urlItem := strings.Split(path, "/")
if urlExist("/" + urlItem[2]) {
secret := r.URL.Query().Get("secret")
if secret == db.HGet(ctx, path, "secret").Val() {
err := db.Del(ctx, path)
if err != nil {
log.Println(err)
}
if verifySecret("/"+urlItem[2], secret) {
deleteContent("/" + urlItem[2])
w.WriteHeader(http.StatusNoContent)
} else {
w.WriteHeader(http.StatusForbidden)
@ -80,12 +78,15 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
} else {
w.WriteHeader(http.StatusNotFound)
}
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
}
func main() {
db = ConnectDB()
currentConfig = GetConfig()
db = connectDB()
currentConfig = getConfig()
listen := currentConfig.host + ":" + currentConfig.port
http.HandleFunc("/", handleRequest)

View file

@ -1,31 +0,0 @@
const codeEditor = document.getElementById('content');
const lineCounter = document.getElementById('lines');
let lineCountCache = 0;
// Update line counter
function updateLineCounter() {
const lineCount = codeEditor.value.split('\n').length;
if (lineCountCache !== lineCount) {
const outarr = Array.from({length: lineCount}, (_, index) => index + 1);
lineCounter.value = outarr.join('\n');
}
lineCountCache = lineCount;
}
codeEditor.addEventListener('input', updateLineCounter);
codeEditor.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
e.preventDefault();
const {value, selectionStart, selectionEnd} = codeEditor;
codeEditor.value = `${value.slice(0, selectionStart)}\t${value.slice(selectionEnd)}`;
codeEditor.setSelectionRange(selectionStart + 1, selectionStart + 1);
updateLineCounter();
}
});
updateLineCounter();

View file

@ -9,15 +9,9 @@
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>New plak • Plakken</title>
<link href="/static/style.css" rel="stylesheet">
<script async src="/static/app.js"></script>
</head>
<body>
<form method="post">
<div>
<label for="lines"></label>
<textarea id="lines" readonly wrap="hard">1</textarea>
</div>
<div>
<label for="content"></label>
<textarea autofocus id="content" name="content" placeholder="Your paste here"></textarea>
<nav>
@ -52,14 +46,13 @@
</select>
</li>
</ul>
<button title="Save plak" type="submit">
<button type="submit" title="Save plak">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<polyline points="9 11 12 14 22 4"></polyline>
<path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
</svg>
</button>
</nav>
</div>
</form>
</body>
</html>

View file

@ -2,7 +2,7 @@
--accent: #be0560;
--background: #141414;
--border: #333;
--text: #e9e9e9;
--text: #e2e2e2;
}
body {
@ -12,35 +12,19 @@ body {
margin: 0;
}
form {
display: flex;
flex-flow: row wrap;
}
button, textarea {
background-color: inherit;
border: none;
outline: none;
resize: none;
}
#lines {
color: #999;
font: 400 14px/1.6 "JetBrains Mono", monospace;
height: calc(100vh - 3rem);
overflow-y: hidden;
padding: 10px 0;
text-align: center;
user-select: none;
width: 26px;
}
#content {
textarea {
color: var(--text);
font: 400 14px/1.6 "JetBrains Mono", monospace;
font: 14px/1.6 "JetBrains Mono", monospace;
height: calc(100vh - 3rem);
padding: 10px 10px 10px 6px;
width: calc(100vw - 42px);
outline: none;
padding: 1rem;
resize: none;
width: calc(100vw - 2rem);
}
pre {
@ -59,7 +43,7 @@ nav {
ul {
display: flex;
flex-flow: row wrap;
gap: 36px;
gap: 2.6rem;
list-style: none;
margin: 0;
padding: 0 1.9rem;
@ -76,7 +60,7 @@ input, select {
color: var(--text);
font-size: 15px;
outline: none;
padding: 6px 8px;
padding: 5px 6px;
transition: border .15s ease;
}

View file

@ -7,7 +7,7 @@ import (
mathrand "math/rand"
)
func GenerateUrl() string {
func generateUrl() string {
listChars := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
b := make([]rune, currentConfig.urlLength)
for i := range b {
@ -17,7 +17,7 @@ func GenerateUrl() string {
return string(b)
}
func GenerateSecret() string {
func generateSecret() string {
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
@ -27,10 +27,14 @@ func GenerateSecret() string {
return hex.EncodeToString(key)
}
func UrlExist(url string) bool {
return db.Exists(ctx, url).Val() == 1
func urlExist(url string) bool {
exist := db.Exists(ctx, url).Val()
return exist == 1
}
func VerifySecret(url string, secret string) bool {
return secret == db.HGet(ctx, url, "secret").Val()
func verifySecret(url string, secret string) bool {
if secret == db.HGet(ctx, url, "secret").Val() {
return true
}
return false
}