mirror of
https://github.com/C4illin/ConvertX.git
synced 2025-11-02 13:03:30 +00:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
961a55cbe5 | ||
|
|
cdf9bad903 | ||
|
|
6769fa2f83 | ||
|
|
3b7ea88b73 | ||
|
|
59310c095d | ||
|
|
c47f0c12fe | ||
|
|
ca71a40485 | ||
|
|
d4e8f376c1 | ||
|
|
14c6ea1e6b | ||
|
|
d6e4d8fbd6 | ||
|
|
460bda62d5 | ||
|
|
d2702ab673 | ||
|
|
e2581f42f5 | ||
|
|
f0fcfc159f | ||
|
|
538c5b60c9 | ||
|
|
2fabb7bbb2 | ||
|
|
e7c34a9c94 | ||
|
|
618f9fce5a | ||
|
|
95dbc9f678 | ||
|
|
aa87bc5c51 | ||
|
|
815de531ed | ||
|
|
cf2b026dc4 | ||
|
|
9ce46aefba | ||
|
|
98b2db7818 | ||
|
|
0229851bf9 | ||
|
|
9e15114fe8 | ||
|
|
7f66a76bb0 | ||
|
|
e9cc8392bb | ||
|
|
d0b89ce74f | ||
|
|
f537c81db7 | ||
|
|
03d3edfff6 | ||
|
|
447b4c5e5c | ||
|
|
cb143209ae | ||
|
|
9c24fe73b5 | ||
|
|
19ae85424b | ||
|
|
22fad99552 | ||
|
|
8144bbef74 | ||
|
|
aad6da0ae8 | ||
|
|
c5f8162a22 |
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## [0.10.1](https://github.com/C4illin/ConvertX/compare/v0.10.0...v0.10.1) (2025-01-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ffmpeg works without ffmpeg_args ([3b7ea88](https://github.com/C4illin/ConvertX/commit/3b7ea88b7382f7c21b120bdc9bda5bb10547f55d)), closes [#212](https://github.com/C4illin/ConvertX/issues/212)
|
||||
|
||||
## [0.10.0](https://github.com/C4illin/ConvertX/compare/v0.9.0...v0.10.0) (2025-01-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add calibre ([03d3edf](https://github.com/C4illin/ConvertX/commit/03d3edfff65c252dd4b8922fc98257c089c1ff74)), closes [#191](https://github.com/C4illin/ConvertX/issues/191)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add FFMPEG_ARGS env variable ([f537c81](https://github.com/C4illin/ConvertX/commit/f537c81db7815df8017f834e3162291197e1c40f)), closes [#190](https://github.com/C4illin/ConvertX/issues/190)
|
||||
* add qt6-qtbase-private-dev from community repo ([95dbc9f](https://github.com/C4illin/ConvertX/commit/95dbc9f678bec7e6e2c03587e1473fb8ff708ea3))
|
||||
* skip account setup when ALLOW_UNAUTHENTICATED is true ([538c5b6](https://github.com/C4illin/ConvertX/commit/538c5b60c9e27a8184740305475245da79bae143))
|
||||
|
||||
## [0.9.0](https://github.com/C4illin/ConvertX/compare/v0.8.1...v0.9.0) (2024-11-21)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM oven/bun:1.1.36-alpine AS base
|
||||
FROM oven/bun:1.1.45-alpine AS base
|
||||
LABEL org.opencontainers.image.source="https://github.com/C4illin/ConvertX"
|
||||
WORKDIR /app
|
||||
|
||||
@@ -51,7 +51,12 @@ RUN apk --no-cache add \
|
||||
vips-jxl \
|
||||
libjxl-tools \
|
||||
assimp \
|
||||
inkscape
|
||||
inkscape \
|
||||
poppler-utils
|
||||
|
||||
RUN apk --no-cache add qt6-qtbase-private-dev --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community/
|
||||
|
||||
RUN apk --no-cache add calibre --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
|
||||
|
||||
# this might be needed for some latex use cases, will add it if needed.
|
||||
# texmf-dist-fontsextra \
|
||||
|
||||
28
README.md
28
README.md
@@ -4,6 +4,7 @@
|
||||
|
||||
[](https://github.com/C4illin/ConvertX/actions/workflows/docker-publish.yml)
|
||||
[](https://github.com/C4illin/ConvertX/pkgs/container/ConvertX)
|
||||
[](https://hub.docker.com/r/c4illin/convertx)
|
||||
[](https://github.com/C4illin/ConvertX/pkgs/container/convertx)
|
||||

|
||||

|
||||
@@ -26,12 +27,13 @@ A self-hosted online file converter. Supports over a thousand different formats.
|
||||
| [libjxl](https://github.com/libjxl/libjxl) | JPEG XL | 11 | 11 |
|
||||
| [resvg](https://github.com/RazrFalcon/resvg) | SVG | 1 | 1 |
|
||||
| [Vips](https://github.com/libvips/libvips) | Images | 45 | 23 |
|
||||
| [Assimp](https://github.com/assimp/assimp) | 3D Assets | 70 | 24 |
|
||||
| [XeLaTeX](https://tug.org/xetex/) | LaTeX | 1 | 1 |
|
||||
| [Calibre](https://calibre-ebook.com/) | E-books | 26 | 19 |
|
||||
| [Pandoc](https://pandoc.org/) | Documents | 43 | 65 |
|
||||
| [GraphicsMagick](http://www.graphicsmagick.org/) | Images | 166 | 133 |
|
||||
| [GraphicsMagick](http://www.graphicsmagick.org/) | Images | 167 | 130 |
|
||||
| [Inkscape](https://inkscape.org/) | Vector images | 7 | 17 |
|
||||
| [FFmpeg](https://ffmpeg.org/) | Video | ~473 | ~280 |
|
||||
| [Assimp](https://github.com/assimp/assimp) | 3D Assets | 77 | 23 |
|
||||
| [FFmpeg](https://ffmpeg.org/) | Video | ~472 | ~199 |
|
||||
|
||||
<!-- many ffmpeg fileformats are duplicates -->
|
||||
|
||||
@@ -51,7 +53,7 @@ services:
|
||||
environment:
|
||||
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() if unset
|
||||
volumes:
|
||||
- convertx:/app/data
|
||||
- ./data:/app/data
|
||||
```
|
||||
|
||||
or
|
||||
@@ -75,11 +77,27 @@ All are optional, JWT_SECRET is recommended to be set.
|
||||
| HTTP_ALLOWED | false | Allow HTTP connections, only set this to true locally |
|
||||
| ALLOW_UNAUTHENTICATED | false | Allow unauthenticated users to use the service, only set this to true locally |
|
||||
| AUTO_DELETE_EVERY_N_HOURS | 24 | Checks every n hours for files older then n hours and deletes them, set to 0 to disable |
|
||||
| WEBROOT | "" | The address to the root path setting this to "/convert" will serve the website on "example.com/convert/" |
|
||||
| WEBROOT | | The address to the root path setting this to "/convert" will serve the website on "example.com/convert/" |
|
||||
| FFMPEG_ARGS | | Arguments to pass to ffmpeg, e.g. `-preset veryfast` |
|
||||
|
||||
> [!WARNING]
|
||||
> If you can't login, make sure you are accessing the service over https or set HTTP_ALLOWED=true
|
||||
|
||||
### Docker images
|
||||
|
||||
There is a `:latest` tag that is updated with every release and a `:main` tag that is updated with every push to the main branch. `:latest` is recommended for normal use.
|
||||
|
||||
The image is available on [GitHub Container Registry](https://github.com/C4illin/ConvertX/pkgs/container/ConvertX) and [Docker Hub](https://hub.docker.com/r/c4illin/convertx).
|
||||
|
||||
| Image | What it is |
|
||||
|-------|------------|
|
||||
| `image: ghcr.io/c4illin/convertx` | The latest release on ghcr |
|
||||
| `image: ghcr.io/c4illin/convertx:main` | The latest commit on ghcr |
|
||||
| `image: c4illin/convertx` | The latest release on docker hub |
|
||||
| `image: c4illin/convertx:main` | The latest commit on docker hub |
|
||||
|
||||
<!-- Dockerhub was introduced in 0.9.0 and older releases -->
|
||||
|
||||
### Tutorial
|
||||
|
||||
Tutorial in french: <https://belginux.com/installer-convertx-avec-docker/>
|
||||
|
||||
33
compose.yaml
33
compose.yaml
@@ -1,16 +1,17 @@
|
||||
services:
|
||||
convertx:
|
||||
build:
|
||||
context: .
|
||||
# dockerfile: Debian.Dockerfile
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
environment: # Defaults are listed below. All are optional.
|
||||
- ACCOUNT_REGISTRATION=true # true or false, doesn't matter for the first account (e.g. keep this to false if you only want one account)
|
||||
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() by default
|
||||
- HTTP_ALLOWED=true # setting this to true is unsafe, only set this to true locally
|
||||
- ALLOW_UNAUTHENTICATED=true # allows anyone to use the service without logging in, only set this to true locally
|
||||
- AUTO_DELETE_EVERY_N_HOURS=1 # checks every n hours for files older then n hours and deletes them, set to 0 to disable
|
||||
- WEBROOT=/convertx # the root path of the web interface, leave empty to disable
|
||||
ports:
|
||||
- 3000:3000
|
||||
services:
|
||||
convertx:
|
||||
build:
|
||||
context: .
|
||||
# dockerfile: Debian.Dockerfile
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
environment: # Defaults are listed below. All are optional.
|
||||
- ACCOUNT_REGISTRATION=true # true or false, doesn't matter for the first account (e.g. keep this to false if you only want one account)
|
||||
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() by default
|
||||
- HTTP_ALLOWED=true # setting this to true is unsafe, only set this to true locally
|
||||
- ALLOW_UNAUTHENTICATED=true # allows anyone to use the service without logging in, only set this to true locally
|
||||
- AUTO_DELETE_EVERY_N_HOURS=1 # checks every n hours for files older then n hours and deletes them, set to 0 to disable
|
||||
# - FFMPEG_ARGS=-hwaccel vulkan # additional arguments to pass to ffmpeg
|
||||
# - WEBROOT=/convertx # the root path of the web interface, leave empty to disable
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
||||
42
package.json
42
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "convertx-frontend",
|
||||
"version": "0.9.0",
|
||||
"version": "0.10.1",
|
||||
"scripts": {
|
||||
"dev": "bun run --watch src/index.tsx",
|
||||
"hot": "bun run --hot src/index.tsx",
|
||||
@@ -13,11 +13,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@elysiajs/cookie": "^0.8.0",
|
||||
"@elysiajs/html": "^1.1.1",
|
||||
"@elysiajs/jwt": "^1.1.1",
|
||||
"@elysiajs/static": "^1.1.1",
|
||||
"@kitajs/html": "^4.2.4",
|
||||
"elysia": "^1.1.25"
|
||||
"@elysiajs/html": "^1.2.0",
|
||||
"@elysiajs/jwt": "^1.2.0",
|
||||
"@elysiajs/static": "^1.2.0",
|
||||
"@kitajs/html": "^4.2.7",
|
||||
"elysia": "^1.2.10"
|
||||
},
|
||||
"module": "src/index.tsx",
|
||||
"type": "module",
|
||||
@@ -25,31 +25,31 @@
|
||||
"start": "bun run src/index.tsx"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.2.3",
|
||||
"@eslint/js": "^9.15.0",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
|
||||
"@kitajs/ts-html-plugin": "^4.1.0",
|
||||
"@eslint/compat": "^1.2.5",
|
||||
"@eslint/js": "^9.18.0",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.4.1",
|
||||
"@kitajs/ts-html-plugin": "^4.1.1",
|
||||
"@total-typescript/ts-reset": "^0.6.1",
|
||||
"@types/bun": "^1.1.13",
|
||||
"@types/bun": "^1.1.16",
|
||||
"@types/eslint-plugin-tailwindcss": "^3.17.0",
|
||||
"@types/eslint__js": "^8.42.3",
|
||||
"@types/node": "^22.9.1",
|
||||
"@types/node": "^22.10.7",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cssnano": "^7.0.6",
|
||||
"eslint": "^9.15.0",
|
||||
"eslint": "^9.18.0",
|
||||
"eslint-plugin-deprecation": "^3.0.0",
|
||||
"eslint-plugin-readable-tailwind": "^1.8.2",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-plugin-tailwindcss": "^3.17.5",
|
||||
"globals": "^15.12.0",
|
||||
"knip": "^5.37.1",
|
||||
"npm-run-all2": "^7.0.1",
|
||||
"postcss": "^8.4.49",
|
||||
"globals": "^15.14.0",
|
||||
"knip": "^5.42.1",
|
||||
"npm-run-all2": "^7.0.2",
|
||||
"postcss": "^8.5.1",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier": "^3.4.2",
|
||||
"tailwind-scrollbar": "^3.1.0",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"typescript": "^5.6.3",
|
||||
"typescript-eslint": "^8.15.0"
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.20.0"
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,12 @@ import { Html } from "@kitajs/html";
|
||||
export const Header = ({
|
||||
loggedIn,
|
||||
accountRegistration,
|
||||
allowUnauthenticated,
|
||||
webroot = "",
|
||||
}: {
|
||||
loggedIn?: boolean;
|
||||
accountRegistration?: boolean;
|
||||
allowUnauthenticated?: boolean;
|
||||
webroot?: string;
|
||||
}) => {
|
||||
let rightNav: JSX.Element;
|
||||
@@ -24,17 +26,19 @@ export const Header = ({
|
||||
History
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class={`
|
||||
text-accent-600 transition-all
|
||||
hover:text-accent-500 hover:underline
|
||||
`}
|
||||
href={`${webroot}/logoff`}
|
||||
>
|
||||
Logout
|
||||
</a>
|
||||
</li>
|
||||
{!allowUnauthenticated ? (
|
||||
<li>
|
||||
<a
|
||||
class={`
|
||||
text-accent-600 transition-all
|
||||
hover:text-accent-500 hover:underline
|
||||
`}
|
||||
href={`${webroot}/logoff`}
|
||||
>
|
||||
Logout
|
||||
</a>
|
||||
</li>
|
||||
) : null}
|
||||
</ul>
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { exec } from "node:child_process";
|
||||
|
||||
// This could be done dynamically by running `ffmpeg -formats` and parsing the output
|
||||
export const properties = {
|
||||
from: {
|
||||
muxer: [
|
||||
object: [
|
||||
"3d",
|
||||
"3ds",
|
||||
"3mf",
|
||||
@@ -84,7 +83,7 @@ export const properties = {
|
||||
],
|
||||
},
|
||||
to: {
|
||||
muxer: [
|
||||
object: [
|
||||
"3ds",
|
||||
"3mf",
|
||||
"assbin",
|
||||
@@ -120,8 +119,6 @@ export async function convert(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
options?: unknown,
|
||||
): Promise<string> {
|
||||
// let command = "ffmpeg";
|
||||
|
||||
const command = `assimp export "${filePath}" "${targetPath}"`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
86
src/converters/calibre.ts
Normal file
86
src/converters/calibre.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { exec } from "node:child_process";
|
||||
|
||||
export const properties = {
|
||||
from: {
|
||||
document: [
|
||||
"azw4",
|
||||
"chm",
|
||||
"cbr",
|
||||
"cbz",
|
||||
"cbt",
|
||||
"cba",
|
||||
"cb7",
|
||||
"djvu",
|
||||
"docx",
|
||||
"epub",
|
||||
"fb2",
|
||||
"htlz",
|
||||
"html",
|
||||
"lit",
|
||||
"lrf",
|
||||
"mobi",
|
||||
"odt",
|
||||
"pdb",
|
||||
"pdf",
|
||||
"pml",
|
||||
"rb",
|
||||
"rtf",
|
||||
"recipe",
|
||||
"snb",
|
||||
"tcr",
|
||||
"txt",
|
||||
],
|
||||
},
|
||||
to: {
|
||||
document: [
|
||||
"azw3",
|
||||
"docx",
|
||||
"epub",
|
||||
"fb2",
|
||||
"html",
|
||||
"htmlz",
|
||||
"lit",
|
||||
"lrf",
|
||||
"mobi",
|
||||
"oeb",
|
||||
"pdb",
|
||||
"pdf",
|
||||
"pml",
|
||||
"rb",
|
||||
"rtf",
|
||||
"snb",
|
||||
"tcr",
|
||||
"txt",
|
||||
"txtz",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export async function convert(
|
||||
filePath: string,
|
||||
fileType: string,
|
||||
convertTo: string,
|
||||
targetPath: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
options?: unknown,
|
||||
): Promise<string> {
|
||||
const command = `ebook-convert "${filePath}" "${targetPath}"`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`stdout: ${stdout}`);
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.error(`stderr: ${stderr}`);
|
||||
}
|
||||
|
||||
resolve("Done");
|
||||
});
|
||||
});
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ import { convert as convertPandoc, properties as propertiesPandoc } from "./pand
|
||||
import { convert as convertresvg, properties as propertiesresvg } from "./resvg";
|
||||
import { convert as convertImage, properties as propertiesImage } from "./vips";
|
||||
import { convert as convertxelatex, properties as propertiesxelatex } from "./xelatex";
|
||||
import { convert as convertCalibre, properties as propertiesCalibre } from "./calibre";
|
||||
|
||||
|
||||
// This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular
|
||||
@@ -56,6 +57,10 @@ const properties: Record<
|
||||
properties: propertiesxelatex,
|
||||
converter: convertxelatex,
|
||||
},
|
||||
calibre: {
|
||||
properties: propertiesCalibre,
|
||||
converter: convertCalibre,
|
||||
},
|
||||
pandoc: {
|
||||
properties: propertiesPandoc,
|
||||
converter: convertPandoc,
|
||||
|
||||
@@ -103,6 +103,16 @@ if (process.env.NODE_ENV === "production") {
|
||||
}
|
||||
});
|
||||
|
||||
exec("ebook-convert --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("ebook-convert (calibre) is not installed");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("bun -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Bun is not installed. wait what");
|
||||
|
||||
@@ -215,6 +215,7 @@ const app = new Elysia({
|
||||
<Header
|
||||
webroot={WEBROOT}
|
||||
accountRegistration={ACCOUNT_REGISTRATION}
|
||||
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
|
||||
/>
|
||||
<main class="w-full px-4">
|
||||
<article class="article">
|
||||
@@ -340,6 +341,7 @@ const app = new Elysia({
|
||||
<Header
|
||||
webroot={WEBROOT}
|
||||
accountRegistration={ACCOUNT_REGISTRATION}
|
||||
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
|
||||
/>
|
||||
<main class="w-full px-4">
|
||||
<article class="article">
|
||||
@@ -457,36 +459,19 @@ const app = new Elysia({
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
})
|
||||
.get("/", async ({ jwt, redirect, cookie: { auth, jobId } }) => {
|
||||
if (FIRST_RUN) {
|
||||
return redirect(`${WEBROOT}/setup`, 302);
|
||||
}
|
||||
if (!ALLOW_UNAUTHENTICATED) {
|
||||
if (FIRST_RUN) {
|
||||
return redirect(`${WEBROOT}/setup`, 302);
|
||||
}
|
||||
|
||||
if (!auth?.value && !ALLOW_UNAUTHENTICATED) {
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
if (!auth?.value) {
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
}
|
||||
}
|
||||
|
||||
// validate jwt
|
||||
let user: ({ id: string } & JWTPayloadSpec) | false = false;
|
||||
if (auth?.value) {
|
||||
user = await jwt.verify(auth.value);
|
||||
|
||||
if (user !== false && user.id) {
|
||||
if (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);
|
||||
|
||||
if (!existingUser) {
|
||||
if (auth?.value) {
|
||||
auth.remove();
|
||||
}
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ALLOW_UNAUTHENTICATED) {
|
||||
if (ALLOW_UNAUTHENTICATED) {
|
||||
const newUserId = String(
|
||||
randomInt(
|
||||
2 ** 24,
|
||||
@@ -512,6 +497,25 @@ const app = new Elysia({
|
||||
maxAge: 24 * 60 * 60,
|
||||
sameSite: "strict",
|
||||
});
|
||||
} else if (auth?.value) {
|
||||
user = await jwt.verify(auth.value);
|
||||
|
||||
if (user !== false && user.id) {
|
||||
if (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);
|
||||
|
||||
if (!existingUser) {
|
||||
if (auth?.value) {
|
||||
auth.remove();
|
||||
}
|
||||
return redirect(`${WEBROOT}/login`, 302);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
@@ -547,7 +551,11 @@ const app = new Elysia({
|
||||
return (
|
||||
<BaseHtml webroot={WEBROOT}>
|
||||
<>
|
||||
<Header webroot={WEBROOT} loggedIn />
|
||||
<Header
|
||||
webroot={WEBROOT}
|
||||
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
|
||||
loggedIn
|
||||
/>
|
||||
<main class="w-full px-4">
|
||||
<article class="article">
|
||||
<h1 class="mb-4 text-xl">Convert</h1>
|
||||
@@ -951,7 +959,11 @@ const app = new Elysia({
|
||||
return (
|
||||
<BaseHtml webroot={WEBROOT} title="ConvertX | Results">
|
||||
<>
|
||||
<Header webroot={WEBROOT} loggedIn />
|
||||
<Header
|
||||
webroot={WEBROOT}
|
||||
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
|
||||
loggedIn
|
||||
/>
|
||||
<main class="w-full px-4">
|
||||
<article class="article">
|
||||
<h1 class="mb-4 text-xl">Results</h1>
|
||||
@@ -1038,7 +1050,11 @@ const app = new Elysia({
|
||||
return (
|
||||
<BaseHtml webroot={WEBROOT} title="ConvertX | Result">
|
||||
<>
|
||||
<Header webroot={WEBROOT} loggedIn />
|
||||
<Header
|
||||
webroot={WEBROOT}
|
||||
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
|
||||
loggedIn
|
||||
/>
|
||||
<main class="w-full px-4">
|
||||
<article class="article">
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
@@ -1284,7 +1300,11 @@ const app = new Elysia({
|
||||
return (
|
||||
<BaseHtml webroot={WEBROOT} title="ConvertX | Converters">
|
||||
<>
|
||||
<Header webroot={WEBROOT} loggedIn />
|
||||
<Header
|
||||
webroot={WEBROOT}
|
||||
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
|
||||
loggedIn
|
||||
/>
|
||||
<main class="w-full px-4">
|
||||
<article class="article">
|
||||
<h1 class="mb-4 text-xl">Converters</h1>
|
||||
|
||||
Reference in New Issue
Block a user