Compare commits
3 Commits
3148affe4c
...
635f16f8ff
| Author | SHA1 | Date | |
|---|---|---|---|
| 635f16f8ff | |||
| 2c1cc78cb3 | |||
| ce7bc124ed |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,6 +15,7 @@ main
|
|||||||
*.out
|
*.out
|
||||||
*.zst
|
*.zst
|
||||||
*.gzip
|
*.gzip
|
||||||
|
*.env
|
||||||
|
|
||||||
bin/
|
bin/
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,9 @@
|
|||||||
module database
|
module database
|
||||||
|
|
||||||
import fleximus.argon2
|
|
||||||
import rand
|
import rand
|
||||||
|
// import db.mysql
|
||||||
|
import db.redis
|
||||||
|
import fleximus.argon2
|
||||||
|
|
||||||
pub struct Crypto {}
|
pub struct Crypto {}
|
||||||
|
|
||||||
@@ -14,3 +16,43 @@ pub fn Crypto.hash_password(password string) !string {
|
|||||||
pub fn Crypto.hash_verify(password string, hash string) !bool {
|
pub fn Crypto.hash_verify(password string, hash string) !bool {
|
||||||
return argon2.verify(hash, password.bytes()) or { return error('argon2 verify failed: ${err}') }
|
return argon2.verify(hash, password.bytes()) or { return error('argon2 verify failed: ${err}') }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct Database {
|
||||||
|
// mut:
|
||||||
|
// conn mysql.DB
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn get_connection(cfg util.Config) !&Database {
|
||||||
|
// // connection := mysql.connect(mysql.Config{
|
||||||
|
// // host: cfg.database.host
|
||||||
|
// // // port: u32(cfg.database.port)
|
||||||
|
// // dbname: 'CDN_DATABASE'
|
||||||
|
// // username: cfg.database.username
|
||||||
|
// // password: cfg.database.password
|
||||||
|
// // })!
|
||||||
|
//
|
||||||
|
// //return &Database{ conn: connection }
|
||||||
|
// return &Database{}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn (mut db Database) query[T](query_fn fn(conn &mysql.Connection) ![]T) ![]T {
|
||||||
|
// result := query_fn(db.conn) or {
|
||||||
|
// // Connection died, reconnect
|
||||||
|
// db.conn = mysql.connect(db.config)!
|
||||||
|
// return query_fn(db.conn)!
|
||||||
|
// }
|
||||||
|
// return result
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub fn Database.test() {}
|
||||||
|
|
||||||
|
pub fn test() ! {
|
||||||
|
mut r := redis.connect(redis.Config{
|
||||||
|
host: 'vpn.security-command.org'
|
||||||
|
port: 6767
|
||||||
|
password: 'SuperSecretPassword123'
|
||||||
|
})!
|
||||||
|
|
||||||
|
pong := r.ping() or { panic(err) }
|
||||||
|
println(pong)
|
||||||
|
}
|
||||||
|
|||||||
22
app/src/database/tables.v
Normal file
22
app/src/database/tables.v
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
module database
|
||||||
|
|
||||||
|
@[table: 'users']
|
||||||
|
struct Users {
|
||||||
|
id int @[primary; serial]
|
||||||
|
name string @[nonnull; unique]
|
||||||
|
password_hash string @[nonnull]
|
||||||
|
}
|
||||||
|
|
||||||
|
@[table: 'login_attempts']
|
||||||
|
struct Logins {
|
||||||
|
ip string @[primary]
|
||||||
|
attempts int @[nonnull]
|
||||||
|
attempt_time string @[default: 'CURRENT_TIMESTAMP'; nonnull]
|
||||||
|
}
|
||||||
|
|
||||||
|
@[table: 'files']
|
||||||
|
struct Files {
|
||||||
|
id int @[primary; serial]
|
||||||
|
path string @[nonnull; unique]
|
||||||
|
visible bool @[default: false; nonnull]
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ module main
|
|||||||
import os
|
import os
|
||||||
import veb
|
import veb
|
||||||
import util
|
import util
|
||||||
|
import database
|
||||||
|
import thomaspeissl.dotenv
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -24,13 +26,15 @@ pub struct App {
|
|||||||
veb.Controller
|
veb.Controller
|
||||||
veb.StaticHandler
|
veb.StaticHandler
|
||||||
veb.Middleware[Context]
|
veb.Middleware[Context]
|
||||||
pub mut:
|
|
||||||
embed util.Embedded
|
|
||||||
pub:
|
pub:
|
||||||
cfg util.Config
|
cfg &util.Config
|
||||||
|
embed util.Embedded
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Auth {}
|
pub struct Auth {
|
||||||
|
pub:
|
||||||
|
app &App
|
||||||
|
}
|
||||||
|
|
||||||
// endpoints
|
// endpoints
|
||||||
|
|
||||||
@@ -80,7 +84,7 @@ pub fn (auth &Auth) register(mut ctx Context) veb.Result {
|
|||||||
// utility
|
// utility
|
||||||
|
|
||||||
fn (mut ctx Context) error_page(code int, short string, long string) string {
|
fn (mut ctx Context) error_page(code int, short string, long string) string {
|
||||||
style := ctx.embed.error_css
|
style := ctx.embed.error_css.clone()
|
||||||
return $tmpl('template/error.html')
|
return $tmpl('template/error.html')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +100,10 @@ pub fn (mut ctx Context) not_found() veb.Result {
|
|||||||
|
|
||||||
// --
|
// --
|
||||||
|
|
||||||
fn populate() &util.Config {
|
fn populate() (&util.Config, &util.Embedded) {
|
||||||
|
dotenv.load()
|
||||||
|
dotenv.require('CDN_DB_HOST', 'CDN_DB_PORT')
|
||||||
|
|
||||||
def_root := $d('root', '.')
|
def_root := $d('root', '.')
|
||||||
def_port := int($d('port', 6767))
|
def_port := int($d('port', 6767))
|
||||||
|
|
||||||
@@ -107,6 +114,8 @@ fn populate() &util.Config {
|
|||||||
root: if os.getenv('CDN_ROOT') != '' { os.getenv('CDN_ROOT').str() } else { def_root }
|
root: if os.getenv('CDN_ROOT') != '' { os.getenv('CDN_ROOT').str() } else { def_root }
|
||||||
port: if os.getenv('CDN_PORT') != '' { os.getenv('CDN_PORT').int() } else { def_port }
|
port: if os.getenv('CDN_PORT') != '' { os.getenv('CDN_PORT').int() } else { def_port }
|
||||||
database: &util.Database{
|
database: &util.Database{
|
||||||
|
host: os.getenv('CDN_DB_HOST').str()
|
||||||
|
port: os.getenv('CDN_DB_PORT').int()
|
||||||
username: if os.getenv('CDN_DB_USERNAME') != '' {
|
username: if os.getenv('CDN_DB_USERNAME') != '' {
|
||||||
os.getenv('CDN_DB_USERNAME').str()
|
os.getenv('CDN_DB_USERNAME').str()
|
||||||
} else {
|
} else {
|
||||||
@@ -118,27 +127,34 @@ fn populate() &util.Config {
|
|||||||
def_pass
|
def_pass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, &util.Embedded{
|
||||||
|
style_css: $embed_file('template/assets/style.css', .zlib).to_string()
|
||||||
|
error_css: $embed_file('template/assets/error.css', .zlib).to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
cfg, mut embed := populate()
|
||||||
mut app := &App{
|
mut app := &App{
|
||||||
cfg: populate()
|
cfg: cfg
|
||||||
|
embed: embed
|
||||||
}
|
}
|
||||||
mut auth := &Auth{}
|
mut auth := &Auth{
|
||||||
app.embed = &util.Embedded{
|
app: &app
|
||||||
style_css: $embed_file('assets/style/style.css', .zlib).to_string()
|
|
||||||
error_css: $embed_file('assets/style/error.css', .zlib).to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
database.test()!
|
||||||
|
|
||||||
|
// db := database.get_connection(app.cfg)!
|
||||||
|
|
||||||
app.register_controller[Auth, Context]('/auth', mut auth)!
|
app.register_controller[Auth, Context]('/auth', mut auth)!
|
||||||
|
|
||||||
app.enable_static_compression = true
|
app.enable_static_compression = true
|
||||||
app.use(veb.encode_auto[Context]())
|
app.use(veb.encode_auto[Context]())
|
||||||
|
|
||||||
app.use(veb.MiddlewareOptions[Context]{
|
app.use(veb.MiddlewareOptions[Context]{
|
||||||
handler: fn [app] (mut ctx Context) bool {
|
handler: fn [mut embed] (mut ctx Context) bool {
|
||||||
ctx.embed = &app.embed
|
ctx.embed = embed
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -170,7 +170,6 @@ body {
|
|||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
background-color: var(--bg-secondary);
|
background-color: var(--bg-secondary);
|
||||||
transition: background-color 0.3s ease, border-color 0.3s ease;
|
transition: background-color 0.3s ease, border-color 0.3s ease;
|
||||||
overflow: scroll;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +243,10 @@ body {
|
|||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon svg {
|
||||||
|
fill: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
.file-list {
|
.file-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
<div class
|
||||||
<div class="breadcrumbs">Folder Path</div>
|
<div class="breadcrumbs">Folder Path</div>
|
||||||
<div class="path-container">
|
<div class="path-container">
|
||||||
@{directory}
|
@{directory}
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ import time
|
|||||||
|
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
pub:
|
pub:
|
||||||
|
host string
|
||||||
|
port int
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub mut:
|
|
||||||
root string
|
|
||||||
port int
|
|
||||||
pub:
|
pub:
|
||||||
|
root string
|
||||||
|
port int
|
||||||
database Database
|
database Database
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +54,8 @@ pub fn Utility.get_icon(ext string, is_dir bool) string {
|
|||||||
'zip': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
'zip': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
||||||
'rar': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
'rar': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
||||||
'7z': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
'7z': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
||||||
|
'zst': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
||||||
|
'gzip': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M640-480v-80h80v80h-80Zm0 80h-80v-80h80v80Zm0 80v-80h80v80h-80ZM447-640l-80-80H160v480h400v-80h80v80h160v-400H640v80h-80v-80H447ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80v-480 480Z"/></svg>'
|
||||||
'mp3': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M430-200q38 0 64-26t26-64v-150h120v-80H480v155q-11-8-23.5-11.5T430-380q-38 0-64 26t-26 64q0 38 26 64t64 26ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
|
'mp3': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M430-200q38 0 64-26t26-64v-150h120v-80H480v155q-11-8-23.5-11.5T430-380q-38 0-64 26t-26 64q0 38 26 64t64 26ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
|
||||||
'mp4': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
|
'mp4': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
|
||||||
'avi': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
|
'avi': '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M360-240h160q17 0 28.5-11.5T560-280v-40l80 42v-164l-80 42v-40q0-17-11.5-28.5T520-480H360q-17 0-28.5 11.5T320-440v160q0 17 11.5 28.5T360-240ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>'
|
||||||
@@ -116,7 +119,7 @@ pub fn Utility.list_files(dir_path string, relative string) ![]FileEntry {
|
|||||||
entries << FileEntry{
|
entries << FileEntry{
|
||||||
name: if is_dir { '${file}/' } else { file }
|
name: if is_dir { '${file}/' } else { file }
|
||||||
abs_path: Utility.normalize_path(full_path)
|
abs_path: Utility.normalize_path(full_path)
|
||||||
path: Utility.normalize_path(full_path).split(relative)[1] // if relative != "" { Utility.normalize_path(full_path.split(relative)[1]) } else { Utility.normalize_path(full_path) }
|
path: Utility.normalize_path(full_path).split(relative)[1] or { 'err' }
|
||||||
is_dir: is_dir
|
is_dir: is_dir
|
||||||
size: if !is_dir { file_info.size } else { 0 }
|
size: if !is_dir { file_info.size } else { 0 }
|
||||||
modified: file_info.mtime
|
modified: file_info.mtime
|
||||||
@@ -191,18 +194,17 @@ pub fn HtmlBuilder.generate_file_list(entries []FileEntry, current_path string)
|
|||||||
for entry in entries {
|
for entry in entries {
|
||||||
if entry.is_dir {
|
if entry.is_dir {
|
||||||
dir_count++
|
dir_count++
|
||||||
file_class := 'directory'
|
html += '<div class="file-row directory">'
|
||||||
html += '<div class="file-row ${file_class}">'
|
html += '<div class="icon">${entry.icon}</div>'
|
||||||
html += '<div>${entry.icon}</div>'
|
|
||||||
html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>'
|
html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>'
|
||||||
html += '<div class="size">-</div>'
|
html += '<div class="size">${Utility.format_size(entry.size)}</div>'
|
||||||
html += '<div class="date">${Utility.format_date(entry.modified)}</div>'
|
html += '<div class="date">${Utility.format_date(entry.modified)}</div>'
|
||||||
html += '</div>'
|
html += '</div>'
|
||||||
} else {
|
} else {
|
||||||
file_count++
|
file_count++
|
||||||
total_size += entry.size
|
total_size += entry.size
|
||||||
html += '<div class="file-row file">'
|
html += '<div class="file-row file">'
|
||||||
html += '<div>${entry.icon}</div>'
|
html += '<div class="icon">${entry.icon}</div>'
|
||||||
html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>'
|
html += '<div class="name"><a href="${entry.path}">${entry.name}</a></div>'
|
||||||
html += '<div class="size">${Utility.format_size(entry.size)}</div>'
|
html += '<div class="size">${Utility.format_size(entry.size)}</div>'
|
||||||
html += '<div class="date">${Utility.format_date(entry.modified)}</div>'
|
html += '<div class="date">${Utility.format_date(entry.modified)}</div>'
|
||||||
|
|||||||
Reference in New Issue
Block a user