Rewriting in GO (currently just posts listing)

This commit is contained in:
Jarkko Toivanen 2024-12-27 15:05:42 +02:00
parent b233fb20db
commit d9776254c6
Signed by: jt
GPG key ID: 9151B109B73ECAD5
95 changed files with 264 additions and 426 deletions

3
.gitignore vendored
View file

@ -1 +1,2 @@
data/ snuffler-web
database.db

View file

@ -1,3 +0,0 @@
FROM docker.io/php:8-apache
COPY src/ /var/www/html/

View file

@ -1,17 +1,4 @@
current_dir := $(dir $(abspath $(firstword $(MAKEFILE_LIST)))) run:
go run main.go
data/: FORCE build:
podman-run: data/ go build main.go
podman build -t snuffler/snuffler-web .
podman run -v ./data/:/var/www/html/data/ -p 8080:80 localhost/snuffler/snuffler-web:dev
docker-run: data/
docker build -t snuffler/snuffler-web:dev .
docker run -v $(current_dir)data/:/var/www/html/data/ -p 8080:80 snuffler/snuffler-web:dev
FORCE:
cp -r src/data ./
chmod 777 data
docker-run-dev: data/ src/
docker run -v $(current_dir)src/:/var/www/html/ -v $(current_dir)data/:/var/www/html/data/ -p 8080:80 snuffler/snuffler-web:dev

View file

@ -1,12 +0,0 @@
version: '3'
services:
snuffler-web:
#image: snuffler/snuffler-web
container_name: snuffler-web
build:
context: .
dockerfile: Dockerfile
volumes:
- ./data/:/var/www/html/data/
ports:
- "8080:80"

21
go.mod Normal file
View file

@ -0,0 +1,21 @@
module jakest.us/snuffler-web
go 1.22.9
require modernc.org/sqlite v1.34.4
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.22.0 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.55.3 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
)

49
go.sum Normal file
View file

@ -0,0 +1,49 @@
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8=
modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=

73
index.html Normal file
View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="/static/style.css" />
<link rel="icon" type="image/x-icon" href="/static/snufficon/excited.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Snuffler</title>
</head>
<body>
<div id="flexout">
<div id="lpanel" class="flexpanel">
<ul>
<li>Kotisivu</li>
<li>Viestit</li>
<li>Kalavaleet</li>
<li>Takasivu</li>
</ul>
</div>
<div id="rpanel" class="flexpanel">
<ul>
<li>Mikko Mällikäs<br /><small>@mmallikas</small></li>
<li>Jarkko Toivanen<br /><small>@jt</small></li>
</ul>
</div>
<div id="centerbox">
<div id="titlebox"><img src="/static/snufficon/excited.png" alt="" />Snuffler</div>
<form id="loginform" method="post" action="login.php">
<input type="text" name="name" placeholder="username" />
<input type="password" name="pass" placeholder="password" />
<input type="submit" name="submit" value="Log in" />
</form>
<a href="logout.php">LOG OUT</a>
<form id="postform" method="post" action="post.php">
<textarea id="postformtextarea" name="text" rows="5" placeholder="Whatcha snuffin' about?"></textarea><br />
<div id="postformactionrow">
<select id="persona" name="persona">
<option value="TODO">TODO</option>
</select>
<input type="submit" id="submit" name="submit" value="Snuff!" />
</div>
</form>
<h1>{{.Title}}</h1>
{{range .Posts}}
<div class="post">
<div class="postinfo">
{{.UserName}}: <strong>{{.PersonaName}}</strong>
<br><small>@{{.UserHandle}}@{{.PersonaHandle}}</small>
</div>
<p>{{.Text}}</p>
<hr><small>{{.Time}}</small>
<span class="postactions">
<img class="reactionaction" src="/static/snufficon/thumbs_up.png" />
<img class="reactionaction" src="/static/snufficon/thumbs_down.png" />
<img class="reactionaction" src="/static/snufficon/joy.png" />
<img class="reactionaction" src="/static/snufficon/sob.png" />
<img class="reactionaction" src="/static/snufficon/heart_eyes.png" />
</span>
</div>
{{end}}
</div>
</div>
</body>
</html>

115
main.go Normal file
View file

@ -0,0 +1,115 @@
package main
import (
"database/sql"
"html/template"
"log"
"net/http"
_ "modernc.org/sqlite"
)
type user struct {
id uint
name string
handle string
pass string
email string
about string
}
type persona struct {
id uint
userid uint
handle string
name string
about string
colour string
}
type Post struct {
Id uint
Time uint
Userid uint
Personaid uint
Text string
PersonaName string
UserName string
PersonaHandle string
UserHandle string
}
type comment struct {
id uint
time uint
userid uint
personaid uint
postid uint
text string
}
type page struct {
Title string
Posts []Post
}
var db *sql.DB
func main() {
var err error
db, err = sql.Open("sqlite", "database.db")
if err != nil {
log.Fatal(err)
}
http.Handle("/static/", http.FileServer(http.Dir("./")))
http.HandleFunc("/", httpRootHandler)
err = http.ListenAndServe(":6900", nil)
if err != nil {
log.Fatal(err)
}
db.Close()
}
func httpRootHandler(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("index.html")
posts, err := getPosts()
if err != nil {
log.Fatal(err)
http.Error(w, http.StatusText(500), 500)
return
}
var p page
p.Title = "Snuffler"
p.Posts = posts
t.Execute(w, p)
}
func getPosts() ([]Post, error) {
rows, err := db.Query("SELECT post.id, post.time, post.userid, post.personaid, post.text, user.name, user.handle, persona.name, persona.handle FROM posts AS post LEFT JOIN users AS user ON post.userid=user.id LEFT JOIN personas AS persona ON post.personaid=persona.id")
if err != nil {
log.Fatal(err)
return nil, err
}
var posts []Post
for rows.Next() {
var post Post
err := rows.Scan(&post.Id, &post.Time, &post.Userid, &post.Personaid, &post.Text, &post.UserName, &post.UserHandle, &post.PersonaName, &post.PersonaHandle)
if err != nil {
log.Fatal(err)
return nil, err
}
posts = append(posts, post)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
return nil, err
}
return posts, nil
}

View file

@ -1,4 +0,0 @@
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
RewriteRule ^ index.php

View file

@ -1,20 +0,0 @@
<?php
$url = explode('/', $_SERVER['REQUEST_URI']);
while ($url[0] !== "api") {
array_shift($url);
}
array_shift($url);
$count = 0;
while (!empty($url[0])) {
switch ($url[0]) {
case 'asd':
echo "asdasd";
break;
default:
echo $url[0] . "\n";
}
$count += 1;
array_shift($url);
}
echo "\n" . $count;
?>

5
src/data/.gitignore vendored
View file

@ -1,5 +0,0 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess

View file

@ -1,2 +0,0 @@
order deny,allow
deny from all

View file

@ -1,2 +0,0 @@
order deny,allow
deny from all

View file

@ -1,213 +0,0 @@
<?php
if(count(get_included_files()) ==1) {
http_response_code(403);
die("403: Forbidden");
}
class DataBase extends SQLite3 {
function __construct() {
$this->open('data/database.db');
$this->exec('PRAGMA foreign_keys=ON;');
$this->exec('PRAGMA full_column_names=ON;');
$this->exec('PRAGMA short_column_names=OFF;');
$sql = "
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY UNIQUE,
pass TEXT,
email TEXT UNIQUE,
handle TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
about TEXT
);
CREATE TABLE IF NOT EXISTS personas (
id INTEGER PRIMARY KEY UNIQUE,
userid INTEGER NOT NULL,
handle TEXT NOT NULL,
name TEXT NOT NULL,
about TEXT,
colour INTEGER,
FOREIGN KEY (userid) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
UNIQUE (userid, handle)
);
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY UNIQUE,
time INTEGER NOT NULL,
userid INTEGER NOT NULL,
personaid INTEGER NOT NULL,
text TEXT NOT NULL,
FOREIGN KEY (userid) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (personaid) REFERENCES personas(id) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS comments (
id INTEGER PRIMARY KEY UNIQUE,
time INTEGER NOT NULL,
userid INTEGER NOT NULL,
personaid INTEGER,
postid INTEGER NOT NULL,
text TEXT NOT NULL,
FOREIGN KEY (postid) REFERENCES posts(id),
FOREIGN KEY (userid) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (personaid) REFERENCES personas(id) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
userid INTEGER NOT NULL,
token TEXT NOT NULL UNIQUE,
lastuse TEXT NOT NULL,
expires TEXT NOT NULL,
FOREIGN KEY (userid) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT OR IGNORE INTO users (id, handle, name, about) VALUES ('0', 'SYSTEM', 'SYSTEM', 'SYSTEM');
";
$ret = $this->exec($sql);
}
function addUser($handle, $name, $about=NULL) {
$id = hexdec(uniqid());
$sql = "INSERT INTO users (id, handle, name, about) VALUES ('$id', '$handle', '$name', '$about')";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function getUserByHandle($handle) {
$handle = $this->escapeString($handle);
$sql = "SELECT * FROM users AS user WHERE handle='$handle';";
$ret = $this->query($sql)->fetchArray(SQLITE3_ASSOC);
if(!$ret) {
return false;
}
return $ret;
}
function addPost($text, $userid=NULL, $personaid=NULL) {
$id = hexdec(uniqid());
$time = time();
$sql = $this->prepare("INSERT INTO posts (id, time, userid, personaid, text) values ('$id', '$time', '$userid', :personaid, '$text')");
$sql->bindParam(':personaid', $personaid, SQLITE3_INTEGER);
$ret = $sql->execute();
if(!$ret) {
die($this->lastErrorMsg());
}
}
function addPersona($userid, $handle, $name, $about=NULL, $colour=NULL) {
$id = hexdec(uniqid());
$sql = "INSERT INTO personas (id, userid, handle, name, about, colour) VALUES ('$id', '$userid', '$handle', '$name', '$about', '$colour');";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function passwordSet($userid, $password=NULL) {
$hash = empty($password) ? NULL : password_hash($password, PASSWORD_DEFAULT);
$sql = "UPDATE USERS SET pass='$hash' WHERE id='$userid';";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function passwordVerify($userid, $password) {
$sql = "SELECT pass FROM users WHERE id='$userid';";
$ret = $this->query($sql)->fetchArray(SQLITE3_NUM);
if(!$ret) {
return false;
}
$dbhash = $ret[0];
if(!$dbhash) {
return false;
}
return password_verify($password, $dbhash);
}
function tokenGen() {
return random_bytes(32);
}
function tokenAdd($userid) {
$token = $this->tokenGen();
$hashed = hash('sha256', $token);
$time = time();
$expires = $time + 2592000; // 30 days
$sql = "INSERT INTO tokens (userid, token, lastuse, expires) VALUES ('$userid', '$hashed', '$time', '$expires');";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
return $token;
}
function tokenRefresh($tokenid) {
$time = time();
$expires = $time + 2592000; // 30 days
$sql = "UPDATE tokens SET lastuse='$time', expires='$expires' WHERE id='$tokenid';";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function tokenRemove($token) {
$hashed = hash('sha256', $token);
$sql = "DELETE FROM tokens WHERE token='$hashed';";
$ret = $this->exec($sql);
if(!$ret) {
die($this->lastErrorMsg());
}
}
function getAuthedUserId($token=NULL) {
if (empty($token)) {
if (empty($_COOKIE['token'])) {
return false;
}
$token = base64_decode($_COOKIE['token']);
}
$hashed = hash('sha256', $token);
$sql = "SELECT id AS id, userid AS userid, expires AS expires FROM tokens WHERE token='$hashed';";
$ret = $this->query($sql)->fetchArray(SQLITE3_ASSOC);
if(!$ret) {
return false;
}
if ($ret['expires'] < time()) {
$this->tokenRemove($token);
return false;
}
$this->tokenRefresh($ret['id']);
return $ret['userid'];
}
function getPosts($userid=NULL, $personaid = NULL) {
$sql = "SELECT * FROM posts AS post LEFT JOIN users AS user ON post.userid=user.id LEFT JOIN personas AS persona ON post.personaid=persona.id;";
$ret = $this->query($sql);
$array = array();
while ($row = $ret->fetchArray(SQLITE3_ASSOC)) {
array_push($array, $row);
}
return $array;
}
function getPersonas($userid=NULL) {
if(!$userid) {
$userid = $this->getAuthedUserId();
}
$sql = "SELECT * FROM personas AS persona WHERE userid='$userid' ORDER BY name;";
$ret = $this->query($sql);
$array = array();
while ($row = $ret->fetchArray(SQLITE3_ASSOC)) {
array_push($array, $row);
}
return $array;
}
}
?>

View file

@ -1,110 +0,0 @@
<?php
require_once "inc/database.php";
function getRandomIcon() {
$files = glob('./snufficon/*.png');
$random_file_num = array_rand($files);
return $files[$random_file_num];;
}
$randomicon = getRandomIcon();
$database = new DataBase();
if(!$database) {
die($database->lastErrorMsg());
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="style.css" />
<link rel="icon" type="image/x-icon" href="snufficon/mouthless.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Snuffler</title>
</head>
<body>
<div id="flexout">
<div id="lpanel" class="flexpanel">
<ul>
<li>Kotisivu</li>
<li>Viestit</li>
<li>Kalavaleet</li>
<li>Takasivu</li>
</ul>
</div>
<div id="rpanel" class="flexpanel">
<ul>
<li>Mikko Mällikäs<br /><small>@mmallikas</small></li>
<li>Jarkko Toivanen<br /><small>@jt</small></li>
</ul>
</div>
<div id="centerbox">
<div id="titlebox"><img src="<?php echo $randomicon; ?>" alt="" />Snuffler</div>
<?php
if (!$database->getAuthedUserId()) {
?>
<form id="loginform" method="post" action="login.php">
<input type="text" name="name" placeholder="username" />
<input type="password" name="pass" placeholder="password" />
<input type="submit" name="submit" value="Log in" />
</form>
<?php
} else {
?>
<a href="logout.php">LOG OUT</a>
<form id="postform" method="post" action="post.php">
<textarea id="postformtextarea" name="text" rows="5" placeholder="Whatcha snuffin' about?"></textarea><br />
<div id="postformactionrow">
<select id="persona" name="persona">
<?php
$personas = $database->getPersonas();
foreach($personas as $persona) {
echo "<option value=" . $persona['persona.id'] . ">" . $persona['persona.name'] . "</option>";
}
?>
</select>
<input type="submit" id="submit" name="submit" value="Snuff!" />
</div>
</form>
<?php
}
?>
<?php
//$database->addPost("Test post", 0);
$posts = array_reverse($database->getPosts());
//var_dump($posts);
foreach($posts as $post) {
echo '<div class="post">';
echo '<div class="postinfo">';
echo $post["user.name"] . ': <strong>' . $post["persona.name"] . '</strong>';
echo '<br><small>@' . $post["user.handle"] . '@' . $post["persona.handle"] . '</small>';
echo '</div>';
echo '<p>' . $post["post.text"] . '</p>';
echo '<hr><small>' . date("D j.n.Y \@ G:i", $post["post.time"]) . '</small>';
echo '
<span class="postactions">
<img class="reactionaction" src="snufficon/thumbs_up.png" />
<img class="reactionaction" src="snufficon/thumbs_down.png" />
<img class="reactionaction" src="snufficon/joy.png" />
<img class="reactionaction" src="snufficon/sob.png" />
<img class="reactionaction" src="snufficon/heart_eyes.png" />
</span>';
echo "</div>";
}
$database->close();
?>
</div>
</div>
</body>
</html>

View file

@ -1,16 +0,0 @@
<?php
if (empty($_POST) || !isset($_POST['submit'])) {
die("Login canceled: no post / no submit");
}
require_once('inc/database.php');
$db = new DataBase();
$user = $db->getUserByHandle($_POST['name']);
if ($db->passwordVerify($user['user.id'], $_POST['pass'])) {
$token = $db->tokenAdd($user['user.id']);
$token64 = base64_encode($token);
$expires = time() + 2592000; // 30 days
setcookie('token', $token64, $expires);
}
header("Location: /");
?>

View file

@ -1,7 +0,0 @@
<?php
setcookie("token", "", 0);
require_once('inc/database.php');
$db = new DataBase();
$db->tokenRemove(base64_decode($_COOKIE['token']));
header("Location: /");
?>

View file

@ -1,14 +0,0 @@
<?php
if (empty($_POST) || !isset($_POST['submit'])) {
die("Post canceled: no post / no submit");
}
require_once('inc/database.php');
$db = new DataBase();
$userid = $db->getAuthedUserId();
$persid = $_POST['persona']; // TODO: CHECK OWNERSHIP! (db schema?)
if($userid) {
$db->addPost($_POST['text'], $userid, $persid);
}
header("Location: /");
?>

View file

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 9 KiB

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 9 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB