From 637104cd35005c9139309cc339d162b6d7089320 Mon Sep 17 00:00:00 2001 From: Germano Rizzo Date: Sat, 16 Mar 2024 10:35:39 +0100 Subject: [PATCH] New infrastructure based on GoLang --- .gitignore | 26 +- backend/.gitignore | 1 + backend/db_ops/backup.go | 72 ++++++ backend/db_ops/create.go | 53 ++++ backend/db_ops/maint.go | 60 +++++ backend/flags/flags.go | 38 +++ backend/go.mod | 32 +++ backend/go.sum | 72 ++++++ .../handlers/get_init_data/get_init_data.go | 35 +++ backend/handlers/get_secret/get_secret.go | 69 ++++++ .../get_secret_status/getSecretStatus.go | 52 ++++ backend/handlers/put_secret/putSecret.go | 94 +++++++ backend/main.go | 100 ++++++++ backend/params/globals.go | 42 ++++ backend/params/params.go | 24 ++ backend/utils/errors.go | 27 ++ backend/utils/utils.go | 61 +++++ frontend/.gitignore | 24 ++ index.html => frontend/index.html | 0 jsconfig.json => frontend/jsconfig.json | 0 .../package-lock.json | 129 +++++----- package.json => frontend/package.json | 0 {public => frontend/public}/favicon.png | Bin frontend/src/App.svelte | 233 +++++++++++++++++ .../src}/ClipboardableField.svelte | 18 ++ frontend/src/Utils.svelte | 175 +++++++++++++ {src => frontend/src}/app.css | 0 {src => frontend/src}/main.js | 0 {src => frontend/src}/vite-env.d.ts | 0 svelte.config.js => frontend/svelte.config.js | 0 vite.config.js => frontend/vite.config.js | 6 +- seif.yaml | 26 -- src/App.svelte | 234 ------------------ src/Utils.svelte | 105 -------- src/lib/Counter.svelte | 10 - 35 files changed, 1352 insertions(+), 466 deletions(-) create mode 100644 backend/.gitignore create mode 100644 backend/db_ops/backup.go create mode 100644 backend/db_ops/create.go create mode 100644 backend/db_ops/maint.go create mode 100644 backend/flags/flags.go create mode 100644 backend/go.mod create mode 100644 backend/go.sum create mode 100644 backend/handlers/get_init_data/get_init_data.go create mode 100644 backend/handlers/get_secret/get_secret.go create mode 100644 backend/handlers/get_secret_status/getSecretStatus.go create mode 100644 backend/handlers/put_secret/putSecret.go create mode 100644 backend/main.go create mode 100644 backend/params/globals.go create mode 100644 backend/params/params.go create mode 100644 backend/utils/errors.go create mode 100644 backend/utils/utils.go create mode 100644 frontend/.gitignore rename index.html => frontend/index.html (100%) rename jsconfig.json => frontend/jsconfig.json (100%) rename package-lock.json => frontend/package-lock.json (87%) rename package.json => frontend/package.json (100%) rename {public => frontend/public}/favicon.png (100%) create mode 100644 frontend/src/App.svelte rename {src => frontend/src}/ClipboardableField.svelte (61%) create mode 100644 frontend/src/Utils.svelte rename {src => frontend/src}/app.css (100%) rename {src => frontend/src}/main.js (100%) rename {src => frontend/src}/vite-env.d.ts (100%) rename svelte.config.js => frontend/svelte.config.js (100%) rename vite.config.js => frontend/vite.config.js (73%) delete mode 100644 seif.yaml delete mode 100644 src/App.svelte delete mode 100644 src/Utils.svelte delete mode 100644 src/lib/Counter.svelte diff --git a/.gitignore b/.gitignore index acf7eab..f9cd75e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,4 @@ # Mine *.db* - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? +bin/ diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..93a464b --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1 @@ +static/ \ No newline at end of file diff --git a/backend/db_ops/backup.go b/backend/db_ops/backup.go new file mode 100644 index 0000000..95aa9dc --- /dev/null +++ b/backend/db_ops/backup.go @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package db_ops + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "seif/params" + "sort" + "strings" + "time" +) + +const bkpTimeFormat = "060102-150405" + +var bkpTimeGlob = strings.Repeat("?", len(bkpTimeFormat)) + +const bkpFile = "seif_%s.db" +const numFiles = 8 + +func Backup() { + var bkpDir = filepath.Join(filepath.Dir(params.DbPath), "backups") + var err error + + if _, err = os.Stat(bkpDir); errors.Is(err, os.ErrNotExist) { + if err = os.Mkdir(bkpDir, 0755); err != nil { + panic(err) + } + } + + // Execute non-concurrently + params.Lock.Lock() + defer params.Lock.Unlock() + + now := time.Now().Format(bkpTimeFormat) + fname := fmt.Sprintf(filepath.Join(bkpDir, bkpFile), now) + _, err = params.Db.Exec("VACUUM INTO ?", fname) + if err != nil { + fmt.Fprintf(os.Stderr, "backup: %s\n", err.Error()) + return + } + + // delete the backup files, except for the last n + list, err := filepath.Glob(fmt.Sprintf(filepath.Join(bkpDir, bkpFile), bkpTimeGlob)) + if err != nil { + fmt.Fprintf(os.Stderr, "sched. task (pruning bkp files): %s\n", err.Error()) + return + } + + sort.Strings(list) + for i := 0; i < len(list)-numFiles; i++ { + os.Remove(list[i]) + } +} diff --git a/backend/db_ops/create.go b/backend/db_ops/create.go new file mode 100644 index 0000000..dac1e3c --- /dev/null +++ b/backend/db_ops/create.go @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package db_ops + +import ( + "fmt" + "seif/params" + "seif/utils" +) + +const DB_VERSION = 1 + +const SQL_CREATE = ` + CREATE TABLE SECRETS ( + ID TEXT PRIMARY KEY, + IV TEXT, + SECRET TEXT, + SHA TEXT, + EXPIRY INTEGER, + TS TEXT + )` + +var SQL_CREATE_2 = fmt.Sprintf("CREATE VIEW VERSION AS SELECT %d AS VERSION", DB_VERSION) + +func InitDb() { + // Execute non-concurrently + params.Lock.Lock() + defer params.Lock.Unlock() + + if _, err := params.Db.Exec(SQL_CREATE); err != nil { + utils.Abort("in creating db: %s", err) + } + + if _, err := params.Db.Exec(SQL_CREATE_2); err != nil { + utils.Abort("in creating db: %s", err) + } +} diff --git a/backend/db_ops/maint.go b/backend/db_ops/maint.go new file mode 100644 index 0000000..8a34963 --- /dev/null +++ b/backend/db_ops/maint.go @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package db_ops + +import ( + "fmt" + "os" + "seif/params" + "seif/utils" + "time" +) + +const maint_period = 5 // min + +const SQL_MAINT = "DELETE FROM SECRETS WHERE TS < DATETIME('now', '-' || EXPIRY || ' days')" + +func maint(allowToPanic bool) { + // Execute non-concurrently + params.Lock.Lock() + defer params.Lock.Unlock() + + if _, err := params.Db.Exec(SQL_MAINT); err != nil { + if allowToPanic { + utils.Abort("in doing cleanup: %s\n", err.Error()) + } else { + fmt.Fprintf(os.Stderr, "in doing maintenance cleanup: %s\n", err.Error()) + } + } + + if _, err := params.Db.Exec("VACUUM"); err != nil { + if allowToPanic { + utils.Abort("in doing vacuum: %s\n", err.Error()) + } else { + fmt.Fprintf(os.Stderr, "in doing maintenance vacuum: %s\n", err.Error()) + } + } +} + +func StartMaint() { + maint(true) + for range time.Tick((maint_period * time.Minute)) { + maint(false) + } +} diff --git a/backend/flags/flags.go b/backend/flags/flags.go new file mode 100644 index 0000000..a415627 --- /dev/null +++ b/backend/flags/flags.go @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package flags + +import ( + "flag" + "seif/params" +) + +func Parse() { + _db := flag.String("db", "./seif.db", "The path of the sqlite database") + _port := flag.Int("port", 34543, "Port") + _maxDays := flag.Int("max-days", 3, "Maximum retention days to allow") + _maxBytes := flag.Int("max-bytes", 1024, "Maximum size, in bytes, of a secret") + + flag.Parse() + + params.DbPath = *_db + params.Port = *_port + params.MaxDays = *_maxDays + params.MaxBytes = *_maxBytes +} diff --git a/backend/go.mod b/backend/go.mod new file mode 100644 index 0000000..cc70a0b --- /dev/null +++ b/backend/go.mod @@ -0,0 +1,32 @@ +module seif + +go 1.22 + +require ( + github.com/gofiber/fiber/v2 v2.52.2 + modernc.org/sqlite v1.29.5 +) + +require ( + github.com/andybalholm/brotli v1.1.0 // indirect + 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/klauspost/compress v1.17.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.52.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + golang.org/x/sys v0.18.0 // indirect + modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect + modernc.org/libc v1.45.0 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.7.2 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect +) diff --git a/backend/go.sum b/backend/go.sum new file mode 100644 index 0000000..367738f --- /dev/null +++ b/backend/go.sum @@ -0,0 +1,72 @@ +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +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/gofiber/fiber/v2 v2.52.2 h1:b0rYH6b06Df+4NyrbdptQL8ifuxw/Tf2DgfkZkDaxEo= +github.com/gofiber/fiber/v2 v2.52.2/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +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/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +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/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +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= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= +github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +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.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.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.19.3 h1:vE9kmJqUcyvNOf8F2Hn8od14SOMq34BiqcZ2tMzLk5c= +modernc.org/cc/v4 v4.19.3/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.11.0 h1:2uc2kRvZLC/oHylsrirRW6f1I4wljQST2BBbm+aKiXM= +modernc.org/ccgo/v4 v4.11.0/go.mod h1:GwrfAtnU6PdZkCWD4XI8wB1T5Xj3fSw9lO/40H1ldys= +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-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.45.0 h1:qmAJZf9tYFqK/SFSFqpBc9uHWGsvoYWtRcMQdG+JEfM= +modernc.org/libc v1.45.0/go.mod h1:YkRHLoN4L70OdO1cVmM83KZhRbRvsc3XogfVzbTXBwE= +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.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +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.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE= +modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= +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= diff --git a/backend/handlers/get_init_data/get_init_data.go b/backend/handlers/get_init_data/get_init_data.go new file mode 100644 index 0000000..6765aae --- /dev/null +++ b/backend/handlers/get_init_data/get_init_data.go @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package get_init_data + +import ( + "seif/params" + + "github.com/gofiber/fiber/v2" +) + +type response struct { + Version string `json:"version"` + MaxDays int `json:"max_days"` +} + +func GetInitData(c *fiber.Ctx) error { + c.JSON(response{Version: params.VERSION, MaxDays: params.MaxDays}) + return c.SendStatus(fiber.StatusOK) +} diff --git a/backend/handlers/get_secret/get_secret.go b/backend/handlers/get_secret/get_secret.go new file mode 100644 index 0000000..2ea633e --- /dev/null +++ b/backend/handlers/get_secret/get_secret.go @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package get_secret + +import ( + "seif/db_ops" + "seif/params" + "seif/utils" + + "github.com/gofiber/fiber/v2" +) + +type Secret struct { + IV string `json:"iv"` + Sec string `json:"secret"` + SHA string `json:"sha"` +} + +type response struct { + Secret *Secret `json:"secret"` +} + +const SQL = "DELETE FROM SECRETS WHERE ID = $1 RETURNING IV, SECRET, SHA" + +func GetSecret(c *fiber.Ctx) error { + id := c.Query("id", "") + + defer func() { go db_ops.Backup() }() + params.Lock.Lock() + defer params.Lock.Unlock() + + ret := response{} + + rows, err := params.Db.Query(SQL, id) + if err != nil { + return utils.SendError(c, fiber.StatusInternalServerError, utils.FHE002, "secret", &err) + } + defer rows.Close() + if rows.Next() { + var secret Secret + err = rows.Scan(&secret.IV, &secret.Sec, &secret.SHA) + if err != nil { + return utils.SendError(c, fiber.StatusInternalServerError, utils.FHE001, "secret", &err) + } + ret.Secret = &secret + } + if err = rows.Err(); err != nil { + return utils.SendError(c, fiber.StatusInternalServerError, utils.FHE003, "secret", &err) + } + + c.JSON(ret) + return c.SendStatus(fiber.StatusOK) +} diff --git a/backend/handlers/get_secret_status/getSecretStatus.go b/backend/handlers/get_secret_status/getSecretStatus.go new file mode 100644 index 0000000..2d492d7 --- /dev/null +++ b/backend/handlers/get_secret_status/getSecretStatus.go @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package get_secret_status + +import ( + "seif/params" + "seif/utils" + + "github.com/gofiber/fiber/v2" +) + +type response struct { + Pristine bool `json:"pristine"` +} + +const SQL_GET_SECRET = "SELECT 1 FROM SECRETS WHERE ID = $1" + +func GetSecretStatus(c *fiber.Ctx) error { + id := c.Query("id", "") + + params.Lock.Lock() + defer params.Lock.Unlock() + + rows, err := params.Db.Query(SQL_GET_SECRET, id) + if err != nil { + return utils.SendError(c, fiber.StatusInternalServerError, utils.FHE001, "secret", &err) + } + defer rows.Close() + ret := rows.Next() + if err = rows.Err(); err != nil { + return utils.SendError(c, fiber.StatusInternalServerError, utils.FHE003, "secret", &err) + } + + c.JSON(response{Pristine: ret}) + return c.SendStatus(fiber.StatusOK) +} diff --git a/backend/handlers/put_secret/putSecret.go b/backend/handlers/put_secret/putSecret.go new file mode 100644 index 0000000..9592a3c --- /dev/null +++ b/backend/handlers/put_secret/putSecret.go @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package put_secret + +import ( + "crypto/rand" + "encoding/base64" + "fmt" + "seif/db_ops" + "seif/handlers/get_secret" + "seif/params" + "seif/utils" + + "github.com/gofiber/fiber/v2" +) + +type request struct { + get_secret.Secret + Expiry int `json:"expiry"` +} + +type response struct { + Id string `json:"id"` +} + +const SQL = ` + INSERT INTO SECRETS (ID, IV, SECRET, SHA, EXPIRY, TS) + VALUES ($1, $2, $3, $4, $5, CURRENT_TIMESTAMP) + RETURNING ID` + +// generateRandomBase64 generates a 42-bit random value encoded in base64. +func generate42bitRandomBase64() (string, error) { + // 42 bits = 5.25 bytes, but we need a whole number of bytes + b := make([]byte, 6) // Using 6 bytes (48 bits) to have a whole number greater than 42 bits + _, err := rand.Read(b) + if err != nil { + return "", err + } + // Mask the last 6 bits of the last byte to zero to ensure only 42 bits are random + b[5] &= 0xC0 // 0xC0 is 11000000 in binary, which sets the last 6 bits to zero + + // Encode to base64 + encoded := base64.URLEncoding.EncodeToString(b) + // Trim the result to the correct length: 7 characters for 42 bits + return encoded[:7], nil +} + +func PutSecret(c *fiber.Ctx) error { + req := new(request) + if err := c.BodyParser(req); err != nil { + return utils.SendError(c, fiber.StatusBadRequest, utils.FHE004, "body", &err) + } + + if len(req.Sec) > params.MaxBytes { + return utils.SendError(c, fiber.StatusBadRequest, utils.FHE005, "", nil) + } + + if req.Expiry < 1 || req.Expiry > params.MaxDays { + return utils.SendError(c, fiber.StatusBadRequest, utils.FHE006, fmt.Sprint(params.MaxDays), nil) + } + + id, err := generate42bitRandomBase64() + if err != nil { + return utils.SendError(c, fiber.StatusBadRequest, utils.FHE007, "", &err) + } + + defer func() { go db_ops.Backup() }() + params.Lock.Lock() + defer params.Lock.Unlock() + + _, err = params.Db.Exec(SQL, id, req.IV, req.Sec, req.SHA, req.Expiry) + if err != nil { + return utils.SendError(c, fiber.StatusInternalServerError, utils.FHE002, "secrets", &err) + } + + c.JSON(response{Id: id}) + return c.SendStatus(fiber.StatusOK) +} diff --git a/backend/main.go b/backend/main.go new file mode 100644 index 0000000..f5bb74f --- /dev/null +++ b/backend/main.go @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package main + +import ( + "database/sql" + "embed" + "fmt" + "net/http" + "seif/db_ops" + "seif/flags" + "seif/handlers/get_init_data" + "seif/handlers/get_secret" + "seif/handlers/get_secret_status" + "seif/handlers/put_secret" + "seif/params" + "seif/utils" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/middleware/filesystem" + "github.com/gofiber/fiber/v2/middleware/recover" + _ "modernc.org/sqlite" +) + +//go:embed static/* +var static embed.FS + +func main() { + flags.Parse() + + dbIsNew := !utils.FileExists(params.DbPath) + + // FIXME don't open a new connection for each operation + var err error + params.Db, err = sql.Open("sqlite", params.DbPath) + if err != nil { + panic(err) + } + defer params.Db.Close() + + // Populates db + if dbIsNew { + db_ops.InitDb() + } else { + // check db version + + row := params.Db.QueryRow("SELECT VERSION FROM VERSION") + var dbVersion int + if err := row.Scan(&dbVersion); err != nil { + panic(err) + } + if dbVersion != db_ops.DB_VERSION { + utils.Abort("DB version is %d but should be %d. Please upgrade the database or the application.", dbVersion, db_ops.DB_VERSION) + } + + // Backup + + db_ops.Backup() + } + + // Maintenance + + go db_ops.StartMaint() + + // server + + app := fiber.New(fiber.Config{ServerHeader: "seif v." + params.VERSION, AppName: "seif", DisableStartupMessage: true}) + + app.Use(recover.New()) + + app.Use("/", filesystem.New(filesystem.Config{ + Root: http.FS(static), + PathPrefix: "static", + })) + + app.Get("/api/getInitData", get_init_data.GetInitData) + app.Delete("/api/getSecret", get_secret.GetSecret) + app.Get("/api/getSecretStatus", get_secret_status.GetSecretStatus) + app.Put("/api/putSecret", put_secret.PutSecret) + + fmt.Println(" - server on port", params.Port) + fmt.Printf(" - all ok. Please open http://localhost:%d\n", params.Port) + app.Listen(fmt.Sprintf(":%d", params.Port)) +} diff --git a/backend/params/globals.go b/backend/params/globals.go new file mode 100644 index 0000000..b933056 --- /dev/null +++ b/backend/params/globals.go @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package params + +import ( + "database/sql" + "fmt" + "sync" +) + +const VERSION = "v0.0.0" + +// https://manytools.org/hacker-tools/ascii-banner/, profile "Small Slant" +const banner = ` ____ _ ___ + / __/__ (_) _/ + _\ \/ -_) / _/ +/___/\__/_/_/` + +var Lock sync.Mutex + +var Db *sql.DB + +func init() { + fmt.Println(banner, VERSION) + fmt.Println() +} diff --git a/backend/params/params.go b/backend/params/params.go new file mode 100644 index 0000000..7e5dfd6 --- /dev/null +++ b/backend/params/params.go @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package params + +var DbPath string +var Port int +var MaxDays int +var MaxBytes int diff --git a/backend/utils/errors.go b/backend/utils/errors.go new file mode 100644 index 0000000..eabf45b --- /dev/null +++ b/backend/utils/errors.go @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package utils + +var FHE001 = "cannot read from %s" +var FHE002 = "cannot write to %s" +var FHE003 = "residual error on resultset" +var FHE004 = "%s is malformed" +var FHE005 = "secret is too long" +var FHE006 = "invalid expiry, must be between 1 and %s days" +var FHE007 = "cannot generate random key" diff --git a/backend/utils/utils.go b/backend/utils/utils.go new file mode 100644 index 0000000..1006ebe --- /dev/null +++ b/backend/utils/utils.go @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2024- Germano Rizzo + * + * This file is part of Seif. + * + * Seif is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Seif is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Seif. If not, see . + */ +package utils + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/gofiber/fiber/v2" +) + +func Abort(msg string, a ...any) { + fmt.Fprintf(os.Stderr, "FATAL: %s\n", fmt.Sprintf(msg, a...)) + os.Exit(-1) +} + +func FileExists(filePath string) bool { + _, err := os.Stat(filePath) + return !os.IsNotExist(err) +} + +type errorr struct { + Code string `json:"code"` + Object string `json:"object"` + Error *string `json:"error"` +} + +func SendError(c *fiber.Ctx, status int, errCode string, obj string, err *error) error { + var errString *string + if err != nil { + _errString := (*err).Error() + errString = &_errString + } + e := errorr{ + Code: errCode, + Object: obj, + Error: errString, + } + + str, _ := json.Marshal(e) + fmt.Fprintf(os.Stderr, "%s\n", str) + c.JSON(e) + return c.SendStatus(status) +} diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/index.html b/frontend/index.html similarity index 100% rename from index.html rename to frontend/index.html diff --git a/jsconfig.json b/frontend/jsconfig.json similarity index 100% rename from jsconfig.json rename to frontend/jsconfig.json diff --git a/package-lock.json b/frontend/package-lock.json similarity index 87% rename from package-lock.json rename to frontend/package-lock.json index fad2e23..26376a1 100644 --- a/package-lock.json +++ b/frontend/package-lock.json @@ -18,13 +18,13 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -383,32 +383,32 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" @@ -421,9 +421,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -431,9 +431,9 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.4.6.tgz", - "integrity": "sha512-zO79p0+DZnXPnF0ltIigWDx/ux7Ni+HRaFOw720Qeivc1azFUrJxTl0OryXVibYNx1hCboGia1NRV3x8RNv4cA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.3.tgz", + "integrity": "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w==", "dev": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", @@ -448,7 +448,7 @@ "node": "^14.18.0 || >= 16" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0", + "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, @@ -470,15 +470,15 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -497,9 +497,9 @@ } }, "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", "dev": true, "dependencies": { "dequal": "^2.0.3" @@ -519,9 +519,9 @@ } }, "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, "node_modules/css-tree": { "version": "2.3.1", @@ -656,9 +656,9 @@ "dev": true }, "node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -680,9 +680,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -715,9 +715,9 @@ "dev": true }, "node_modules/postcss": { - "version": "8.4.30", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz", - "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "dev": true, "funding": [ { @@ -734,7 +734,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -743,9 +743,9 @@ } }, "node_modules/rollup": { - "version": "3.29.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.2.tgz", - "integrity": "sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -768,23 +768,24 @@ } }, "node_modules/svelte": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.1.tgz", - "integrity": "sha512-LpLqY2Jr7cRxkrTc796/AaaoMLF/1ax7cto8Ot76wrvKQhrPmZ0JgajiWPmg9mTSDqO16SSLiD17r9MsvAPTmw==", + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", + "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", "acorn": "^8.9.0", "aria-query": "^5.3.0", - "axobject-query": "^3.2.1", + "axobject-query": "^4.0.0", "code-red": "^1.0.3", "css-tree": "^2.3.1", "estree-walker": "^3.0.3", "is-reference": "^3.0.1", "locate-character": "^3.0.0", - "magic-string": "^0.30.0", + "magic-string": "^0.30.4", "periscopic": "^3.1.0" }, "engines": { @@ -804,18 +805,18 @@ } }, "node_modules/sweetalert2": { - "version": "11.7.28", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.7.28.tgz", - "integrity": "sha512-9895DVuYTDlV4Hx4IJablFKMdSqzwpy0PKycztbO4cXnOeVMmw55weOq4gcZAh3/tAyunCKjApFDrlSAcswwcA==", + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.6.tgz", + "integrity": "sha512-CINZPLZXZRSZqSOE7H7j1F7X8e8O1kLOiXPmtJn1DYxvXsKBr3d16d90+IcwTTs7dJww20h8r8QIxIwsLGX+6A==", "funding": { "type": "individual", "url": "https://github.com/sponsors/limonte" } }, "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz", + "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -868,12 +869,12 @@ } }, "node_modules/vitefu": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", - "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", "dev": true, "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0" + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { "vite": { @@ -882,4 +883,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.json b/frontend/package.json similarity index 100% rename from package.json rename to frontend/package.json diff --git a/public/favicon.png b/frontend/public/favicon.png similarity index 100% rename from public/favicon.png rename to frontend/public/favicon.png diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte new file mode 100644 index 0000000..c5483ff --- /dev/null +++ b/frontend/src/App.svelte @@ -0,0 +1,233 @@ + + +{#if !!initData} + +
 
+
+
+
 
+
+ {#if token == ""} + {#if link == ""} +

+ Input your secret here. It will be encrypted and saved to the + server, and an one-time link will be generated. +

+