f034_sqlite_database #19

Merged
jared merged 34 commits from f034_sqlite_database into development 2025-07-24 14:34:39 +02:00
9 changed files with 96 additions and 91 deletions
Showing only changes of commit 34d5034a71 - Show all commits

View File

@@ -3,42 +3,42 @@ import jsSHA from 'jssha';
const db = new Database('./src/lib/data/tatort.db'); const db = new Database('./src/lib/data/tatort.db');
let create_stmt = `CREATE TABLE IF NOT EXISTS users let createSQLStmt = `CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY AUTOINCREMENT, (id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL, name TEXT NOT NULL,
pw TEXT NOT NULL)`; pw TEXT NOT NULL)`;
db.exec(create_stmt); db.exec(createSQLStmt);
// check if there are any users; if not add one default admin one // check if there are any users; if not add one default admin one
let pw = 'pass-123'; let password = 'pass-123';
let hashed_pw = new jsSHA('SHA-512', 'TEXT').update(pw).getHash('HEX'); let hashedPassword = new jsSHA('SHA-512', 'TEXT').update(password).getHash('HEX');
let check_ins_stmt = `INSERT INTO users (name, pw) SELECT 'admin', '${hashed_pw}' let checkInsertSQLStmt = `INSERT INTO users (name, pw) SELECT 'admin', '${hashedPassword}'
WHERE NOT EXISTS (SELECT * FROM users);`; WHERE NOT EXISTS (SELECT * FROM users);`;
db.exec(check_ins_stmt); db.exec(checkInsertSQLStmt);
let users_stmt = `SELECT * FROM USERS`; let usersSQLStmt = `SELECT * FROM USERS`;
let stmt = db.prepare(users_stmt); let SQLStatement = db.prepare(usersSQLStmt);
console.log(`\n`, `*** Users table`); console.log(`\n`, `*** Users table`);
trachi93 marked this conversation as resolved Outdated

[JB] console.log entfernen

[JB] console.log entfernen
for (const usr of stmt.iterate()) { for (const usr of SQLStatement.iterate()) {
console.log(`[r] ${usr.name} + ${usr.pw}`); console.log(`[r] ${usr.name} + ${usr.pw}`);
} }
// cases table // cases table
create_stmt = `CREATE TABLE IF NOT EXISTS cases createSQLStmt = `CREATE TABLE IF NOT EXISTS cases
(id INTEGER PRIMARY KEY AUTOINCREMENT, (id INTEGER PRIMARY KEY AUTOINCREMENT,
token TEXT NOT NULL UNIQUE, token TEXT NOT NULL UNIQUE,
name TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE,
pw TEXT NOT NULL)`; pw TEXT NOT NULL)`;
db.exec(create_stmt); db.exec(createSQLStmt);
let cases_stmt = `SELECT * FROM cases`; let casesSQLStmt = `SELECT * FROM cases`;
stmt = db.prepare(cases_stmt); SQLStatement = db.prepare(casesSQLStmt);
console.log(`\n`, `*** Cases table`); console.log(`\n`, `*** Cases table`);
for (const usr of stmt.iterate()) { for (const usr of SQLStatement.iterate()) {
console.log(`[r] ${usr.name} + ${usr.token} + ${usr.pw}`); console.log(`[r] ${usr.name} + ${usr.token} + ${usr.pw}`);
} }

View File

@@ -19,18 +19,18 @@ export function decryptToken(token: string) {
} }
export function authenticate(user, pass) { export function authenticate(user, pass) {
let token; let JWTToken;
// hash user password // hash user password
let hashed_pw = new jsSHA('SHA-512', 'TEXT').update(pass).getHash('HEX'); let hashedPW = new jsSHA('SHA-512', 'TEXT').update(pass).getHash('HEX');
let get_usr_stmt = 'SELECT name, pw FROM users WHERE name = ?'; let getUserSQLStmt = 'SELECT name, pw FROM users WHERE name = ?';
const row = db.prepare(get_usr_stmt).get(user); const row = db.prepare(getUserSQLStmt).get(user);
let stored_pw = row.pw; let storedPW = row.pw;
if (hashed_pw && hashed_pw === stored_pw) { if (hashedPW && hashedPW === storedPW) {
token = createToken({ id: user, admin: true }); JWTToken = createToken({ id: user, admin: true });
} }
return token; return JWTToken;
} }

View File

@@ -28,23 +28,28 @@ export const getVorgangByCaseId = async (caseId: string) => {
/** /**
* Get Vorgang * Get Vorgang
* @param caseId * @param caseToken
* @returns caseObj with keys `token`, `name`, `pw` || undefined * @returns caseObj with keys `token`, `name`, `pw` || undefined
*/ */
export const getVorgang = function (caseId: string) { export const getVorgangByToken = function (caseToken: string) {
let getVorgang_stmt = `SELECT token, name, pw FROM cases WHERE token = ?`; let getVorgangSQLStmt = `SELECT token, name, pw FROM cases WHERE token = ?`;
const stmt = db.prepare(getVorgang_stmt); const statement = db.prepare(getVorgangSQLStmt);
const res = stmt.get(caseId); const result = statement.get(caseToken);
return res; return result;
}; };
/**
* Get Vorgang
* @param caseName
* @returns caseObj with keys `token`, `name`, `pw` || undefined
*/
export const getVorgangByName = function (caseName: string) { export const getVorgangByName = function (caseName: string) {
let getVorgangByName_stmt = `SELECT token, name, pw FROM cases WHERE name = ?`; let getVorgangByNameSQLStmt = `SELECT token, name, pw FROM cases WHERE name = ?`;
const stmt = db.prepare(getVorgangByName_stmt); const statement = db.prepare(getVorgangByNameSQLStmt);
const res = stmt.get(caseName); const result = statement.get(caseName);
return res; return result;
}; };
/** /**
@@ -53,9 +58,9 @@ export const getVorgangByName = function (caseName: string) {
* @returns int: number of changes * @returns int: number of changes
*/ */
export const deleteVorgangByName = function (caseName: string) { export const deleteVorgangByName = function (caseName: string) {
let delete_stmt = 'DELETE FROM cases WHERE name = ?'; let deleteSQLStmt = 'DELETE FROM cases WHERE name = ?';
const stmt = db.prepare(delete_stmt); const statement = db.prepare(deleteSQLStmt);
const info = stmt.run(caseName); const info = statement.run(caseName);
return info.changes; return info.changes;
}; };
@@ -84,11 +89,11 @@ export const getListOfVorgänge = async () => {
* @returns list with of available cases * @returns list with of available cases
*/ */
export const getVorgaenge = function () { export const getVorgaenge = function () {
let getVorgaenge_stmt = `SELECT token, name, pw from cases`; let getVorgaengeSQLStmt = `SELECT token, name, pw from cases`;
const stmt = db.prepare(getVorgaenge_stmt); const statement = db.prepare(getVorgaengeSQLStmt);
const res = stmt.all(); const result = statement.all();
const vorgaenge_list = []; const vorgaenge_list = [];
for (const r of res) { for (const r of result) {
const vorg = { token: r.token, name: r.name, pw: r.pw }; const vorg = { token: r.token, name: r.name, pw: r.pw };
vorgaenge_list.push(vorg); vorgaenge_list.push(vorg);
} }
@@ -121,11 +126,11 @@ export const checkIfVorgangExists = async (caseId: string | null) => {
return true; return true;
}; };
export const vorgangExists = function (caseId: string | null) { export const vorgangExists = function (caseToken: string | null) {
if (!caseId) { if (!caseToken) {
return fail(400, { return fail(400, {
success: false, success: false,
caseId, caseId: caseToken,
error: { message: 'Die Vorgangsnummer darf nicht leer sein.' } error: { message: 'Die Vorgangsnummer darf nicht leer sein.' }
}); });
} }
@@ -133,16 +138,16 @@ export const vorgangExists = function (caseId: string | null) {
let vorgaenge = getVorgaenge(); let vorgaenge = getVorgaenge();
const vorgaenge_tokens = vorgaenge.map((vorg) => vorg.token); const vorgaenge_tokens = vorgaenge.map((vorg) => vorg.token);
const found = vorgaenge_tokens.indexOf(caseId) != -1; const found = vorgaenge_tokens.indexOf(caseToken) != -1;
return found; return found;
}; };
export const vorgangNameExists = function (caseName: string) { export const vorgangNameExists = function (caseName: string) {
let vorgaenge = getVorgaenge(); let vorgaenge = getVorgaenge();
const vorgaenge_names = vorgaenge.map((vorg) => vorg.name); const vorgaengeNames = vorgaenge.map((vorg) => vorg.name);
const found = vorgaenge_names.indexOf(caseName) != -1; const found = vorgaengeNames.indexOf(caseName) != -1;
return found; return found;
}; };
@@ -174,7 +179,7 @@ export const tokenValid = function (caseId, caseToken) {
return false; return false;
} }
const vorg = getVorgang(caseId); const vorg = getVorgangByToken(caseId);
if (!vorg || vorg.pw !== caseToken) { if (!vorg || vorg.pw !== caseToken) {
return false; return false;

View File

@@ -21,29 +21,29 @@ export const actions = {
const vorgang = data.get('vorgang'); const vorgang = data.get('vorgang');
const name = data.get('name'); const name = data.get('name');
const type = data.get('type'); const type = data.get('type');
const code = data.get('zugangscode'); const pw = data.get('zugangscode');
const fileName = data.get('fileName'); const fileName = data.get('fileName');
// store case in database // store case in database
// skip if Vorgang exists and token not changed // skip if Vorgang exists and token not changed
const vorgang_exists = vorgangNameExists(vorgang); const vorgangExists = vorgangNameExists(vorgang);
let token; let token;
if (!vorgang_exists) { if (!vorgangExists) {
token = uuidv4(); token = uuidv4();
let insert_stmt = `INSERT INTO cases (token, name, pw) VALUES (?, ?, ?)`; let insertSQLStmt = `INSERT INTO cases (token, name, pw) VALUES (?, ?, ?)`;
const stmt = db.prepare(insert_stmt); const statement = db.prepare(insertSQLStmt);
stmt.run(token, vorgang, code); statement.run(token, vorgang, pw);
} else { } else {
// vorgang exists // vorgang exists
// check if PW was changed, and update DB if it was // check if PW was changed, and update DB if it was
const vorg = getVorgangByName(vorgang); const vorg = getVorgangByName(vorg);
token = vorg.token; token = vorg.token;
if (vorg.pw != code) { if (vorg.pw != pw) {
let update_stmt = `UPDATE cases SET pw = ? WHERE name = ?`; let updateSQLStmt = `UPDATE cases SET pw = ? WHERE name = ?`;
const stmt = db.prepare(update_stmt); const statement = db.prepare(updateSQLStmt);
stmt.run(code, vorgang); statement.run(pw, vorg);
} }
} }

View File

@@ -23,12 +23,12 @@
.slice(2, 2 + code_len); .slice(2, 2 + code_len);
} }
let zugangscode = '' let zugangscode = ''
let zugangscode_old = '' let zugangscodeOld = ''
$: zugangscode_old = generate_token(); $: zugangscodeOld = generate_token();
$: zugangscode = zugangscode_old $: zugangscode = zugangscodeOld
let case_existing = undefined; let caseExisting = undefined;
$: case_existing = false; $: caseExisting = false;
let name = ''; let name = '';
let etag: string | null = null; let etag: string | null = null;
@@ -152,37 +152,37 @@
} }
// `/(angemeldet)/view` return true or false // `/(angemeldet)/view` return true or false
async function case_exists(case_name: string) { async function caseExists(caseName: string) {
if (case_name == '') { if (caseName == '') {
zugangscode = zugangscode_old; zugangscode = zugangscodeOld;
return; return;
} }
let url = `/api/list/${case_name}` let url = `/api/list/${caseName}`
const response = await fetch(url, { method: 'HEAD'}); const response = await fetch(url, { method: 'HEAD'});
const status = response.status; const status = response.status;
if (status == 200) { if (status == 200) {
case_existing = true; caseExisting = true;
const code = await get_code(case_name); const code = await getCode(caseName);
zugangscode = code; zugangscode = code;
return true return true
} else { } else {
case_existing = false; caseExisting = false;
zugangscode = zugangscode_old; zugangscode = zugangscodeOld;
return false return false
} }
} }
async function get_code(case_no: string) { async function getCode(caseName: string) {
if (case_no == '') return; if (caseName == '') return;
let url = `/api/list/${case_no}/code`; let url = `/api/list/${caseName}/code`;
const response = await fetch(url); const response = await fetch(url);
if (response.status == 200) { if (response.status == 200) {
@@ -226,14 +226,14 @@
id="vorgang" id="vorgang"
autocomplete={vorgang} autocomplete={vorgang}
class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
on:input={() => case_exists(vorgang)} on:input={() => caseExists(vorgang)}
/> />
</div> </div>
</div> </div>
{#if formErrors?.vorgang} {#if formErrors?.vorgang}
<p class="block text-sm leading-6 text-red-900 mt-2">{formErrors.vorgang}</p> <p class="block text-sm leading-6 text-red-900 mt-2">{formErrors.vorgang}</p>
{/if} {/if}
{#if case_existing && vorgang.length > 0} {#if caseExisting && vorgang.length > 0}
<span>Datei wird zum existierenden Vorgang hinzugefügt.</span> <span>Datei wird zum existierenden Vorgang hinzugefügt.</span>
{:else if vorgang.length > 0} {:else if vorgang.length > 0}
<span>Neuer Vorgang wird angelegt.</span> <span>Neuer Vorgang wird angelegt.</span>
@@ -284,7 +284,7 @@
type="text" type="text"
name="zugangscode" name="zugangscode"
id="zugangscode" id="zugangscode"
on:input="{ (ev) => { zugangscode_old = ev.target.value }}" on:input="{ (ev) => { zugangscodeOld = ev.target.value }}"
class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
/> />
@@ -292,7 +292,7 @@
<button <button
class="rounded-md bg-blue-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" class="rounded-md bg-blue-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
on:click="{() => { on:click="{() => {
zugangscode = zugangscode_old = generate_token(); }}" zugangscode = zugangscodeOld = generate_token(); }}"
type="button"> type="button">
Generiere Zugangscode Generiere Zugangscode
</button> </button>

View File

@@ -1,4 +1,4 @@
import { getVorgang, getVorgangByCaseId } from '$lib/server/vorgangService'; import { getVorgangByToken, getVorgangByCaseId } from '$lib/server/vorgangService';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params, url }) => { export const load: PageServerLoad = async ({ params, url }) => {
@@ -6,7 +6,7 @@ export const load: PageServerLoad = async ({ params, url }) => {
const caseToken = url.searchParams.get('token'); const caseToken = url.searchParams.get('token');
const crimesList = await getVorgangByCaseId(caseId); const crimesList = await getVorgangByCaseId(caseId);
const vorg = getVorgang(caseId); const vorg = getVorgangByToken(caseId);
return { return {
crimesList, crimesList,

View File

@@ -143,7 +143,7 @@
<div class="flex flex-col items-center justify-center w-full"> <div class="flex flex-col items-center justify-center w-full">
<h1 class="text-xl">Vorgang {vorg.name}</h1> <h1 class="text-xl">Vorgang {vorg.name}</h1>
{#if data?.user?.admin} {#if data?.user?.admin}
Zugangscode: {vorg.pw} Zugangspasswort: {vorg.pw}
<Button on:click={() => setClipboard($page.url.toString().split('?')[0])}>Copy Link</Button> <Button on:click={() => setClipboard($page.url.toString().split('?')[0])}>Copy Link</Button>
{/if} {/if}
</div> </div>

View File

@@ -2,7 +2,7 @@ import { client } from '$lib/minio';
import { db } from '$lib/server/dbService'; import { db } from '$lib/server/dbService';
import { import {
deleteVorgangByName, deleteVorgangByName,
getVorgang, getVorgangByToken,
getVorgangByName, getVorgangByName,
vorgangNameExists vorgangNameExists
} from '$lib/server/vorgangService'; } from '$lib/server/vorgangService';
@@ -11,11 +11,11 @@ export async function DELETE({ params }) {
const vorgang = params.vorgang; const vorgang = params.vorgang;
const vorg = getVorgangByName(vorgang); const vorg = getVorgangByName(vorgang);
let vorg_token = vorg.token; let vorgangToken = vorg.token;
const object_list = await new Promise((resolve, reject) => { const object_list = await new Promise((resolve, reject) => {
const res = []; const res = [];
const items_str = client.listObjects('tatort', vorg_token, true); const items_str = client.listObjects('tatort', vorgangToken, true);
items_str.on('data', (obj) => { items_str.on('data', (obj) => {
res.push(obj.name); res.push(obj.name);
@@ -35,9 +35,9 @@ export async function DELETE({ params }) {
} }
export async function HEAD({ params }) { export async function HEAD({ params }) {
const vorgang_name = params.vorgang; const vorgangName = params.vorgang;
const existing = vorgangNameExists(vorgang_name); const existing = vorgangNameExists(vorgangName);
if (existing) { if (existing) {
return new Response(null, { status: 200 }); return new Response(null, { status: 200 });

View File

@@ -3,14 +3,14 @@ import { db } from '$lib/server/dbService';
/** @type {import('./$types').RequestHandler} */ /** @type {import('./$types').RequestHandler} */
export async function GET({ params }) { export async function GET({ params }) {
const vorgang_name = params.vorgang; const vorgangName = params.vorgang;
let get_code_stmt = `SELECT pw FROM cases WHERE name = ?;`; let getCodeSQLStmt = `SELECT pw FROM cases WHERE name = ?;`;
const row = db.prepare(get_code_stmt).get(vorgang_name); const row = db.prepare(getCodeSQLStmt).get(vorgangName);
let pw = row.pw; let password = row.pw;
if (pw) { if (password) {
return new Response(pw, { status: 200 }); return new Response(password, { status: 200 });
} else { } else {
return new Response(null, { status: 404 }); return new Response(null, { status: 404 });
} }