start migrationg to prisma-orm
This commit is contained in:
parent
9a8d7a36b9
commit
ae2cd5e61f
18 changed files with 374 additions and 200 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { Cookie } from "elysia";
|
||||
import db from "../db/db";
|
||||
import prisma from "../db/db";
|
||||
import { MAX_CONVERT_PROCESS } from "../helpers/env";
|
||||
import { normalizeFiletype, normalizeOutputFiletype } from "../helpers/normalizeFiletype";
|
||||
import { convert as convertassimp, properties as propertiesassimp } from "./assimp";
|
||||
|
|
@ -146,10 +146,6 @@ export async function handleConvert(
|
|||
converterName: string,
|
||||
jobId: Cookie<string | undefined>,
|
||||
) {
|
||||
const query = db.query(
|
||||
"INSERT INTO file_names (job_id, file_name, output_file_name, status) VALUES (?1, ?2, ?3, ?4)",
|
||||
);
|
||||
|
||||
for (const chunk of chunks(fileNames, MAX_CONVERT_PROCESS)) {
|
||||
const toProcess: Promise<string>[] = [];
|
||||
for (const fileName of chunk) {
|
||||
|
|
@ -165,9 +161,16 @@ export async function handleConvert(
|
|||
toProcess.push(
|
||||
new Promise((resolve, reject) => {
|
||||
mainConverter(filePath, fileType, convertTo, targetPath, {}, converterName)
|
||||
.then((r) => {
|
||||
.then(async (r) => {
|
||||
if (jobId.value) {
|
||||
query.run(jobId.value, fileName, newFileName, r);
|
||||
await prisma.fileName.create({
|
||||
data: {
|
||||
jobId: parseInt(jobId.value, 10),
|
||||
fileName,
|
||||
outputFileName: newFileName,
|
||||
status: r,
|
||||
},
|
||||
});
|
||||
}
|
||||
resolve(r);
|
||||
})
|
||||
|
|
|
|||
43
src/db/db.ts
43
src/db/db.ts
|
|
@ -1,41 +1,8 @@
|
|||
import { Database } from "bun:sqlite";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
const db = new Database("./data/mydb.sqlite", { create: true });
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
if (!db.query("SELECT * FROM sqlite_master WHERE type='table'").get()) {
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
email TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS file_names (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
job_id INTEGER NOT NULL,
|
||||
file_name TEXT NOT NULL,
|
||||
output_file_name TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'not started',
|
||||
FOREIGN KEY (job_id) REFERENCES jobs(id)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS jobs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
date_created TEXT NOT NULL,
|
||||
status TEXT DEFAULT 'not started',
|
||||
num_files INTEGER DEFAULT 0,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
PRAGMA user_version = 1;`);
|
||||
}
|
||||
// Initialize the database schema using Prisma migrations instead of raw SQL.
|
||||
// Ensure to run `npx prisma migrate dev` to apply the schema changes.
|
||||
|
||||
const dbVersion = (db.query("PRAGMA user_version").get() as { user_version?: number }).user_version;
|
||||
if (dbVersion === 0) {
|
||||
db.exec("ALTER TABLE file_names ADD COLUMN status TEXT DEFAULT 'not started';");
|
||||
db.exec("PRAGMA user_version = 1;");
|
||||
console.log("Updated database to version 1.");
|
||||
}
|
||||
|
||||
// enable WAL mode
|
||||
db.exec("PRAGMA journal_mode = WAL;");
|
||||
|
||||
export default db;
|
||||
export default prisma;
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
export class Filename {
|
||||
id!: number;
|
||||
job_id!: number;
|
||||
file_name!: string;
|
||||
output_file_name!: string;
|
||||
status!: string;
|
||||
}
|
||||
|
||||
export class Jobs {
|
||||
finished_files!: number;
|
||||
id!: number;
|
||||
user_id!: number;
|
||||
date_created!: string;
|
||||
status!: string;
|
||||
num_files!: number;
|
||||
files_detailed!: Filename[];
|
||||
}
|
||||
|
||||
export class User {
|
||||
id!: number;
|
||||
email!: string;
|
||||
password!: string;
|
||||
}
|
||||
|
|
@ -4,8 +4,7 @@ import { html } from "@elysiajs/html";
|
|||
import { staticPlugin } from "@elysiajs/static";
|
||||
import { Elysia } from "elysia";
|
||||
import "./helpers/printVersions";
|
||||
import db from "./db/db";
|
||||
import { Jobs } from "./db/types";
|
||||
import prisma from "./db/db";
|
||||
import { AUTO_DELETE_EVERY_N_HOURS, WEBROOT } from "./helpers/env";
|
||||
import { chooseConverter } from "./pages/chooseConverter";
|
||||
import { convert } from "./pages/convert";
|
||||
|
|
@ -69,25 +68,28 @@ app.listen(3000);
|
|||
|
||||
console.log(`🦊 Elysia is running at http://${app.server?.hostname}:${app.server?.port}${WEBROOT}`);
|
||||
|
||||
const clearJobs = () => {
|
||||
const jobs = db
|
||||
.query("SELECT * FROM jobs WHERE date_created < ?")
|
||||
.as(Jobs)
|
||||
.all(new Date(Date.now() - AUTO_DELETE_EVERY_N_HOURS * 60 * 60 * 1000).toISOString());
|
||||
const clearJobs = async () => {
|
||||
const jobs = await prisma.job.findMany({
|
||||
where: {
|
||||
dateCreated: {
|
||||
lt: new Date(Date.now() - AUTO_DELETE_EVERY_N_HOURS * 60 * 60 * 1000),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
for (const job of jobs) {
|
||||
// delete the directories
|
||||
rmSync(`${outputDir}${job.user_id}/${job.id}`, {
|
||||
rmSync(`${outputDir}${job.userId}/${job.id}`, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
rmSync(`${uploadsDir}${job.user_id}/${job.id}`, {
|
||||
rmSync(`${uploadsDir}${job.userId}/${job.id}`, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
|
||||
// delete the job
|
||||
db.query("DELETE FROM jobs WHERE id = ?").run(job.id);
|
||||
await prisma.job.delete({ where: { id: job.id } });
|
||||
}
|
||||
|
||||
setTimeout(clearJobs, AUTO_DELETE_EVERY_N_HOURS * 60 * 60 * 1000);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import { Elysia, t } from "elysia";
|
|||
import sanitize from "sanitize-filename";
|
||||
import { outputDir, uploadsDir } from "..";
|
||||
import { handleConvert } from "../converters/main";
|
||||
import db from "../db/db";
|
||||
import { Jobs } from "../db/types";
|
||||
import prisma from "../db/db";
|
||||
import { WEBROOT } from "../helpers/env";
|
||||
import { normalizeFiletype } from "../helpers/normalizeFiletype";
|
||||
import { userService } from "./user";
|
||||
|
|
@ -25,10 +24,15 @@ export const convert = new Elysia().use(userService).post(
|
|||
return redirect(`${WEBROOT}/`, 302);
|
||||
}
|
||||
|
||||
const existingJob = db
|
||||
.query("SELECT * FROM jobs WHERE id = ? AND user_id = ?")
|
||||
.as(Jobs)
|
||||
.get(jobId.value, user.id);
|
||||
const parsedJobId = parseInt(jobId.value, 10);
|
||||
const parsedUserId = parseInt(user.id, 10);
|
||||
|
||||
const existingJob = await prisma.job.findFirst({
|
||||
where: {
|
||||
id: parsedJobId,
|
||||
userId: parsedUserId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingJob) {
|
||||
return redirect(`${WEBROOT}/`, 302);
|
||||
|
|
@ -61,17 +65,23 @@ export const convert = new Elysia().use(userService).post(
|
|||
return redirect(`${WEBROOT}/`, 302);
|
||||
}
|
||||
|
||||
db.query("UPDATE jobs SET num_files = ?1, status = 'pending' WHERE id = ?2").run(
|
||||
fileNames.length,
|
||||
jobId.value,
|
||||
);
|
||||
await prisma.job.update({
|
||||
where: { id: parsedJobId },
|
||||
data: {
|
||||
numFiles: fileNames.length,
|
||||
status: "pending",
|
||||
},
|
||||
});
|
||||
|
||||
// Start the conversion process in the background
|
||||
handleConvert(fileNames, userUploadsDir, userOutputDir, convertTo, converterName, jobId)
|
||||
.then(() => {
|
||||
.then(async () => {
|
||||
// All conversions are done, update the job status to 'completed'
|
||||
if (jobId.value) {
|
||||
db.query("UPDATE jobs SET status = 'completed' WHERE id = ?1").run(jobId.value);
|
||||
await prisma.job.update({
|
||||
where: { id: parsedJobId },
|
||||
data: { status: "completed" },
|
||||
});
|
||||
}
|
||||
|
||||
// Delete all uploaded files in userUploadsDir
|
||||
|
|
|
|||
|
|
@ -12,9 +12,12 @@ export const deleteFile = new Elysia().use(userService).post(
|
|||
return redirect(`${WEBROOT}/`, 302);
|
||||
}
|
||||
|
||||
const existingJob = await db
|
||||
.query("SELECT * FROM jobs WHERE id = ? AND user_id = ?")
|
||||
.get(jobId.value, user.id);
|
||||
const existingJob = await db.job.findFirst({
|
||||
where: {
|
||||
id: parseInt(jobId.value, 10),
|
||||
userId: parseInt(user.id, 10),
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingJob) {
|
||||
return redirect(`${WEBROOT}/`, 302);
|
||||
|
|
|
|||
|
|
@ -4,32 +4,35 @@ import { outputDir, uploadsDir } from "..";
|
|||
import db from "../db/db";
|
||||
import { WEBROOT } from "../helpers/env";
|
||||
import { userService } from "./user";
|
||||
import { Jobs } from "../db/types";
|
||||
|
||||
export const deleteJob = new Elysia().use(userService).get(
|
||||
"/delete/:userId/:jobId",
|
||||
async ({ params, redirect, user }) => {
|
||||
const job = db
|
||||
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
||||
.as(Jobs)
|
||||
.get(user.id, params.jobId);
|
||||
const job = await db.job.findFirst({
|
||||
where: {
|
||||
userId: parseInt(user.id, 10),
|
||||
id: parseInt(params.jobId, 10),
|
||||
},
|
||||
});
|
||||
|
||||
if (!job) {
|
||||
return redirect(`${WEBROOT}/results`, 302);
|
||||
}
|
||||
|
||||
// delete the directories
|
||||
rmSync(`${outputDir}${job.user_id}/${job.id}`, {
|
||||
rmSync(`${outputDir}${job.userId}/${job.id}`, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
rmSync(`${uploadsDir}${job.user_id}/${job.id}`, {
|
||||
rmSync(`${uploadsDir}${job.userId}/${job.id}`, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
|
||||
// delete the job
|
||||
db.query("DELETE FROM jobs WHERE id = ?").run(job.id);
|
||||
await db.job.delete({
|
||||
where: { id: job.id },
|
||||
});
|
||||
return redirect(`${WEBROOT}/history`, 302);
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,9 +12,12 @@ export const download = new Elysia()
|
|||
.get(
|
||||
"/download/:userId/:jobId/:fileName",
|
||||
async ({ params, redirect, user }) => {
|
||||
const job = await db
|
||||
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
||||
.get(user.id, params.jobId);
|
||||
const job = await db.job.findFirst({
|
||||
where: {
|
||||
userId: parseInt(user.id, 10),
|
||||
id: parseInt(params.jobId, 10),
|
||||
},
|
||||
});
|
||||
|
||||
if (!job) {
|
||||
return redirect(`${WEBROOT}/results`, 302);
|
||||
|
|
@ -34,9 +37,12 @@ export const download = new Elysia()
|
|||
.get(
|
||||
"/archive/:userId/:jobId",
|
||||
async ({ params, redirect, user }) => {
|
||||
const job = await db
|
||||
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
||||
.get(user.id, params.jobId);
|
||||
const job = await db.job.findFirst({
|
||||
where: {
|
||||
userId: parseInt(user.id, 10),
|
||||
id: parseInt(params.jobId, 10),
|
||||
},
|
||||
});
|
||||
|
||||
if (!job) {
|
||||
return redirect(`${WEBROOT}/results`, 302);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { Elysia } from "elysia";
|
||||
import { BaseHtml } from "../components/base";
|
||||
import { Header } from "../components/header";
|
||||
import db from "../db/db";
|
||||
import { Filename, Jobs } from "../db/types";
|
||||
import prisma from "../db/db";
|
||||
import { ALLOW_UNAUTHENTICATED, HIDE_HISTORY, LANGUAGE, WEBROOT } from "../helpers/env";
|
||||
import { userService } from "./user";
|
||||
|
||||
|
|
@ -17,17 +16,20 @@ export const history = new Elysia().use(userService).get(
|
|||
return redirect(`${WEBROOT}/login`, 302);
|
||||
}
|
||||
|
||||
let userJobs = db.query("SELECT * FROM jobs WHERE user_id = ?").as(Jobs).all(user.id).reverse();
|
||||
const userId = parseInt(user.id, 10);
|
||||
|
||||
for (const job of userJobs) {
|
||||
const files = db.query("SELECT * FROM file_names WHERE job_id = ?").as(Filename).all(job.id);
|
||||
|
||||
job.finished_files = files.length;
|
||||
job.files_detailed = files;
|
||||
}
|
||||
|
||||
// Filter out jobs with no files
|
||||
userJobs = userJobs.filter((job) => job.num_files > 0);
|
||||
const userJobs = await prisma.job.findMany({
|
||||
where: {
|
||||
userId,
|
||||
files: {
|
||||
some: {}, // Ensures only jobs with files are included
|
||||
},
|
||||
},
|
||||
orderBy: { id: "desc" },
|
||||
include: {
|
||||
files: true,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<BaseHtml webroot={WEBROOT} title="ConvertX | Results">
|
||||
|
|
@ -127,9 +129,9 @@ export const history = new Elysia().use(userService).get(
|
|||
/>
|
||||
</svg>
|
||||
</td>
|
||||
<td safe>{new Date(job.date_created).toLocaleTimeString(LANGUAGE)}</td>
|
||||
<td>{job.num_files}</td>
|
||||
<td class="max-sm:hidden">{job.finished_files}</td>
|
||||
<td safe>{new Date(job.dateCreated).toLocaleTimeString(LANGUAGE)}</td>
|
||||
<td>{job.numFiles}</td>
|
||||
<td class="max-sm:hidden">{job.files.length}</td>
|
||||
<td safe>{job.status}</td>
|
||||
<td>
|
||||
<a
|
||||
|
|
@ -147,10 +149,10 @@ export const history = new Elysia().use(userService).get(
|
|||
<td colspan="6">
|
||||
<div class="p-2 text-sm text-neutral-500">
|
||||
<div class="mb-1 font-semibold">Detailed File Information:</div>
|
||||
{job.files_detailed.map((file: Filename) => (
|
||||
{job.files.map((file) => (
|
||||
<div class="flex items-center">
|
||||
<span class="w-5/12 truncate" title={file.file_name} safe>
|
||||
{file.file_name}
|
||||
<span class="w-5/12 truncate" title={file.fileName} safe>
|
||||
{file.fileName}
|
||||
</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -164,8 +166,8 @@ export const history = new Elysia().use(userService).get(
|
|||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<span class="w-5/12 truncate" title={file.output_file_name} safe>
|
||||
{file.output_file_name}
|
||||
<span class="w-5/12 truncate" title={file.outputFileName} safe>
|
||||
{file.outputFileName}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Elysia } from "elysia";
|
|||
import { BaseHtml } from "../components/base";
|
||||
import { Header } from "../components/header";
|
||||
import db from "../db/db";
|
||||
import { Filename, Jobs } from "../db/types";
|
||||
import { Job, FileName } from "@prisma/client";
|
||||
import { ALLOW_UNAUTHENTICATED, WEBROOT } from "../helpers/env";
|
||||
import { DownloadIcon } from "../icons/download";
|
||||
import { DeleteIcon } from "../icons/delete";
|
||||
|
|
@ -19,8 +19,8 @@ function ResultsArticle({
|
|||
user: {
|
||||
id: string;
|
||||
} & JWTPayloadSpec;
|
||||
job: Jobs;
|
||||
files: Filename[];
|
||||
job: Job;
|
||||
files: FileName[];
|
||||
outputPath: string;
|
||||
}) {
|
||||
return (
|
||||
|
|
@ -29,11 +29,11 @@ function ResultsArticle({
|
|||
<h1 class="text-xl">Results</h1>
|
||||
<div class="flex flex-row gap-4">
|
||||
<a
|
||||
style={files.length !== job.num_files ? "pointer-events: none;" : ""}
|
||||
style={files.length !== job.numFiles ? "pointer-events: none;" : ""}
|
||||
href={`${WEBROOT}/archive/${user.id}/${job.id}`}
|
||||
download={`converted_files_${job.id}.tar`}
|
||||
class="flex btn-primary flex-row gap-2 text-contrast"
|
||||
{...(files.length !== job.num_files ? { disabled: true, "aria-busy": "true" } : "")}
|
||||
{...(files.length !== job.numFiles ? { disabled: true, "aria-busy": "true" } : "")}
|
||||
>
|
||||
<DownloadIcon /> <p>Tar</p>
|
||||
</a>
|
||||
|
|
@ -41,18 +41,18 @@ function ResultsArticle({
|
|||
<DownloadIcon /> <p>All</p>
|
||||
</button>
|
||||
<a
|
||||
style={files.length !== job.num_files ? "pointer-events: none;" : ""}
|
||||
style={files.length !== job.numFiles ? "pointer-events: none;" : ""}
|
||||
class="flex btn-primary flex-row gap-2 text-contrast"
|
||||
href={`${WEBROOT}/delete/${user.id}/${job.id}`}
|
||||
{...(files.length !== job.num_files ? { disabled: true, "aria-busy": "true" } : "")}
|
||||
{...(files.length !== job.numFiles ? { disabled: true, "aria-busy": "true" } : "")}
|
||||
>
|
||||
<DeleteIcon /> <p>Delete</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<progress
|
||||
max={job.num_files}
|
||||
{...(files.length === job.num_files ? { value: files.length } : "")}
|
||||
max={job.numFiles}
|
||||
{...(files.length === job.numFiles ? { value: files.length } : "")}
|
||||
class={`
|
||||
mb-4 inline-block h-2 w-full appearance-none overflow-hidden rounded-full border-0
|
||||
bg-neutral-700 bg-none text-accent-500 accent-accent-500
|
||||
|
|
@ -101,7 +101,7 @@ function ResultsArticle({
|
|||
{files.map((file) => (
|
||||
<tr>
|
||||
<td safe class="max-w-[20vw] truncate">
|
||||
{file.output_file_name}
|
||||
{file.outputFileName}
|
||||
</td>
|
||||
<td safe>{file.status}</td>
|
||||
<td class="flex flex-row gap-4">
|
||||
|
|
@ -110,7 +110,7 @@ function ResultsArticle({
|
|||
text-accent-500 underline
|
||||
hover:text-accent-400
|
||||
`}
|
||||
href={`${WEBROOT}/download/${outputPath}${file.output_file_name}`}
|
||||
href={`${WEBROOT}/download/${outputPath}${file.outputFileName}`}
|
||||
>
|
||||
<EyeIcon />
|
||||
</a>
|
||||
|
|
@ -119,8 +119,8 @@ function ResultsArticle({
|
|||
text-accent-500 underline
|
||||
hover:text-accent-400
|
||||
`}
|
||||
href={`${WEBROOT}/download/${outputPath}${file.output_file_name}`}
|
||||
download={file.output_file_name}
|
||||
href={`${WEBROOT}/download/${outputPath}${file.outputFileName}`}
|
||||
download={file.outputFileName}
|
||||
>
|
||||
<DownloadIcon />
|
||||
</a>
|
||||
|
|
@ -143,10 +143,15 @@ export const results = new Elysia()
|
|||
job_id.remove();
|
||||
}
|
||||
|
||||
const job = db
|
||||
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
||||
.as(Jobs)
|
||||
.get(user.id, params.jobId);
|
||||
const userId = parseInt(user.id, 10);
|
||||
const jobId = parseInt(params.jobId, 10);
|
||||
|
||||
const job = await db.job.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
id: jobId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!job) {
|
||||
set.status = 404;
|
||||
|
|
@ -155,12 +160,13 @@ export const results = new Elysia()
|
|||
};
|
||||
}
|
||||
|
||||
const outputPath = `${user.id}/${params.jobId}/`;
|
||||
const outputPath = `${userId}/${jobId}/`;
|
||||
|
||||
const files = db
|
||||
.query("SELECT * FROM file_names WHERE job_id = ?")
|
||||
.as(Filename)
|
||||
.all(params.jobId);
|
||||
const files = await db.fileName.findMany({
|
||||
where: {
|
||||
jobId,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<BaseHtml webroot={WEBROOT} title="ConvertX | Result">
|
||||
|
|
@ -189,10 +195,15 @@ export const results = new Elysia()
|
|||
job_id.remove();
|
||||
}
|
||||
|
||||
const job = db
|
||||
.query("SELECT * FROM jobs WHERE user_id = ? AND id = ?")
|
||||
.as(Jobs)
|
||||
.get(user.id, params.jobId);
|
||||
const userId = parseInt(user.id, 10);
|
||||
const jobId = parseInt(params.jobId, 10);
|
||||
|
||||
const job = await db.job.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
id: jobId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!job) {
|
||||
set.status = 404;
|
||||
|
|
@ -201,12 +212,13 @@ export const results = new Elysia()
|
|||
};
|
||||
}
|
||||
|
||||
const outputPath = `${user.id}/${params.jobId}/`;
|
||||
const outputPath = `${userId}/${jobId}/`;
|
||||
|
||||
const files = db
|
||||
.query("SELECT * FROM file_names WHERE job_id = ?")
|
||||
.as(Filename)
|
||||
.all(params.jobId);
|
||||
const files = await db.fileName.findMany({
|
||||
where: {
|
||||
jobId,
|
||||
},
|
||||
});
|
||||
|
||||
return <ResultsArticle user={user} job={job} files={files} outputPath={outputPath} />;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { BaseHtml } from "../components/base";
|
|||
import { Header } from "../components/header";
|
||||
import { getAllTargets } from "../converters/main";
|
||||
import db from "../db/db";
|
||||
import { User } from "../db/types";
|
||||
import {
|
||||
ACCOUNT_REGISTRATION,
|
||||
ALLOW_UNAUTHENTICATED,
|
||||
|
|
@ -31,6 +30,8 @@ export const root = new Elysia().use(userService).get(
|
|||
|
||||
// validate jwt
|
||||
let user: ({ id: string } & JWTPayloadSpec) | false = false;
|
||||
let userId: number | null = null;
|
||||
|
||||
if (ALLOW_UNAUTHENTICATED) {
|
||||
const newUserId = String(
|
||||
UNAUTHENTICATED_USER_SHARING
|
||||
|
|
@ -42,6 +43,8 @@ export const root = new Elysia().use(userService).get(
|
|||
});
|
||||
|
||||
user = { id: newUserId };
|
||||
userId = parseInt(newUserId, 10);
|
||||
|
||||
if (!auth) {
|
||||
return {
|
||||
message: "No auth cookie, perhaps your browser is blocking cookies.",
|
||||
|
|
@ -64,8 +67,13 @@ export const root = new Elysia().use(userService).get(
|
|||
user.id &&
|
||||
(Number.parseInt(user.id) < 2 ** 24 || !ALLOW_UNAUTHENTICATED)
|
||||
) {
|
||||
// Make sure user exists in db
|
||||
const existingUser = db.query("SELECT * FROM users WHERE id = ?").as(User).get(user.id);
|
||||
userId = parseInt(user.id, 10);
|
||||
|
||||
const existingUser = await db.user.findFirst({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingUser) {
|
||||
if (auth?.value) {
|
||||
|
|
@ -76,19 +84,29 @@ export const root = new Elysia().use(userService).get(
|
|||
}
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
if (!user || userId === null) {
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
}
|
||||
|
||||
// create a new job
|
||||
db.query("INSERT INTO jobs (user_id, date_created) VALUES (?, ?)").run(
|
||||
user.id,
|
||||
new Date().toISOString(),
|
||||
);
|
||||
await db.job.create({
|
||||
data: {
|
||||
userId,
|
||||
dateCreated: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
|
||||
const { id } = db
|
||||
.query("SELECT id FROM jobs WHERE user_id = ? ORDER BY id DESC")
|
||||
.get(user.id) as { id: number };
|
||||
const { id } = await db.job.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
orderBy: {
|
||||
id: "desc",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
}) as { id: number };
|
||||
|
||||
if (!jobId) {
|
||||
return { message: "Cookies should be enabled to use this app." };
|
||||
|
|
|
|||
|
|
@ -11,9 +11,12 @@ export const upload = new Elysia().use(userService).post(
|
|||
return redirect(`${WEBROOT}/`, 302);
|
||||
}
|
||||
|
||||
const existingJob = await db
|
||||
.query("SELECT * FROM jobs WHERE id = ? AND user_id = ?")
|
||||
.get(jobId.value, user.id);
|
||||
const existingJob = await db.job.findFirst({
|
||||
where: {
|
||||
id: parseInt(jobId.value, 10),
|
||||
userId: parseInt(user.id, 10),
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingJob) {
|
||||
return redirect(`${WEBROOT}/`, 302);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import { randomUUID } from "node:crypto";
|
||||
import { jwt } from "@elysiajs/jwt";
|
||||
import { Elysia, t } from "elysia";
|
||||
import { BaseHtml } from "../components/base";
|
||||
import { Header } from "../components/header";
|
||||
import db from "../db/db";
|
||||
import { User } from "../db/types";
|
||||
import prisma from "../db/db";
|
||||
import {
|
||||
ACCOUNT_REGISTRATION,
|
||||
ALLOW_UNAUTHENTICATED,
|
||||
|
|
@ -12,8 +9,10 @@ import {
|
|||
HTTP_ALLOWED,
|
||||
WEBROOT,
|
||||
} from "../helpers/env";
|
||||
import { BaseHtml } from "../components/base";
|
||||
import { Header } from "../components/header";
|
||||
|
||||
export let FIRST_RUN = db.query("SELECT * FROM users").get() === null || false;
|
||||
export let FIRST_RUN = (await prisma.user.findFirst()) === null || false;
|
||||
|
||||
export const userService = new Elysia({ name: "user/service" })
|
||||
.use(
|
||||
|
|
@ -191,7 +190,7 @@ export const user = new Elysia()
|
|||
FIRST_RUN = false;
|
||||
}
|
||||
|
||||
const existingUser = await db.query("SELECT * FROM users WHERE email = ?").get(email);
|
||||
const existingUser = await prisma.user.findUnique({ where: { email } });
|
||||
if (existingUser) {
|
||||
set.status = 400;
|
||||
return {
|
||||
|
|
@ -200,9 +199,12 @@ export const user = new Elysia()
|
|||
}
|
||||
const savedPassword = await Bun.password.hash(password);
|
||||
|
||||
db.query("INSERT INTO users (email, password) VALUES (?, ?)").run(email, savedPassword);
|
||||
|
||||
const user = db.query("SELECT * FROM users WHERE email = ?").as(User).get(email);
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email,
|
||||
password: savedPassword,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
set.status = 500;
|
||||
|
|
@ -218,7 +220,7 @@ export const user = new Elysia()
|
|||
if (!auth) {
|
||||
set.status = 500;
|
||||
return {
|
||||
message: "No auth cookie, perhaps your browser is blocking cookies.",
|
||||
message: "Failed to authenticate user.",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +320,7 @@ export const user = new Elysia()
|
|||
.post(
|
||||
"/login",
|
||||
async function handler({ body, set, redirect, jwt, cookie: { auth } }) {
|
||||
const existingUser = db.query("SELECT * FROM users WHERE email = ?").as(User).get(body.email);
|
||||
const existingUser = await prisma.user.findUnique({ where: { email: body.email } });
|
||||
|
||||
if (!existingUser) {
|
||||
set.status = 403;
|
||||
|
|
@ -381,7 +383,9 @@ export const user = new Elysia()
|
|||
return redirect(`${WEBROOT}/`, 302);
|
||||
}
|
||||
|
||||
const userData = db.query("SELECT * FROM users WHERE id = ?").as(User).get(user.id);
|
||||
const userId = Number(user.id);
|
||||
|
||||
const userData = await prisma.user.findUnique({ where: { id: userId } });
|
||||
|
||||
if (!userData) {
|
||||
return redirect(`${WEBROOT}/`, 302);
|
||||
|
|
@ -465,7 +469,10 @@ export const user = new Elysia()
|
|||
if (!user) {
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
}
|
||||
const existingUser = db.query("SELECT * FROM users WHERE id = ?").as(User).get(user.id);
|
||||
|
||||
const userId = Number(user.id);
|
||||
|
||||
const existingUser = await prisma.user.findUnique({ where: { id: userId } });
|
||||
|
||||
if (!existingUser) {
|
||||
if (auth?.value) {
|
||||
|
|
@ -483,30 +490,22 @@ export const user = new Elysia()
|
|||
};
|
||||
}
|
||||
|
||||
const fields = [];
|
||||
const values = [];
|
||||
const updates: { email?: string; password?: string } = {};
|
||||
|
||||
if (body.email) {
|
||||
const existingUser = await db
|
||||
.query("SELECT id FROM users WHERE email = ?")
|
||||
.as(User)
|
||||
.get(body.email);
|
||||
if (existingUser && existingUser.id.toString() !== user.id) {
|
||||
const emailInUse = await prisma.user.findUnique({ where: { email: body.email } });
|
||||
if (emailInUse && emailInUse.id !== userId) {
|
||||
set.status = 409;
|
||||
return { message: "Email already in use." };
|
||||
}
|
||||
fields.push("email");
|
||||
values.push(body.email);
|
||||
updates.email = body.email;
|
||||
}
|
||||
if (body.newPassword) {
|
||||
fields.push("password");
|
||||
values.push(await Bun.password.hash(body.newPassword));
|
||||
updates.password = await Bun.password.hash(body.newPassword);
|
||||
}
|
||||
|
||||
if (fields.length > 0) {
|
||||
db.query(
|
||||
`UPDATE users SET ${fields.map((field) => `${field}=?`).join(", ")} WHERE id=?`,
|
||||
).run(...values, user.id);
|
||||
if (Object.keys(updates).length > 0) {
|
||||
await prisma.user.update({ where: { id: userId }, data: updates });
|
||||
}
|
||||
|
||||
return redirect(`${WEBROOT}/`, 302);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue