removed all unused api routes and components
This commit is contained in:
parent
5a941d3883
commit
0badf0bf76
11 changed files with 1 additions and 381 deletions
|
|
@ -1,65 +0,0 @@
|
|||
// app/api/auth/me/route.ts
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
const DIRECTUS_URL = process.env.DIRECTUS_URL!;
|
||||
const ACCESS_COOKIE = "ma_at";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
/**
|
||||
* GET /api/auth/me
|
||||
* Returns the current Directus user using the access token in "ma_at".
|
||||
* Mirrors the shape you’re already expecting on the client:
|
||||
* { id, username, display_name, first_name, last_name, email, ... }
|
||||
*/
|
||||
export async function GET(_req: NextRequest) {
|
||||
try {
|
||||
if (!DIRECTUS_URL) {
|
||||
return NextResponse.json({ error: "Missing DIRECTUS_URL" }, { status: 500 });
|
||||
}
|
||||
|
||||
// Prefer cookie; allow Authorization header for flexibility
|
||||
const cookie = _req.cookies.get(ACCESS_COOKIE)?.value;
|
||||
const authHeader = _req.headers.get("authorization") || "";
|
||||
const bearer =
|
||||
authHeader?.toLowerCase().startsWith("bearer ")
|
||||
? authHeader.slice(7).trim()
|
||||
: cookie;
|
||||
|
||||
if (!bearer) {
|
||||
// No token: treat as not signed in (same semantics as your client)
|
||||
return NextResponse.json({ error: "not-signed-in" }, { status: 401 });
|
||||
}
|
||||
|
||||
const url = `${DIRECTUS_URL}/users/me?fields=id,username,display_name,first_name,last_name,email`;
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
Authorization: `Bearer ${bearer}`,
|
||||
},
|
||||
cache: "no-store",
|
||||
});
|
||||
|
||||
const text = await res.text();
|
||||
let json: any = null;
|
||||
try {
|
||||
json = text ? JSON.parse(text) : null;
|
||||
} catch {
|
||||
// non-JSON from Directus; keep raw text for error messages
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
const msg = json?.errors?.[0]?.message || json?.error || text || "Directus error";
|
||||
const status = res.status === 401 || res.status === 403 ? res.status : 500;
|
||||
return NextResponse.json({ error: msg }, { status });
|
||||
}
|
||||
|
||||
// Directus often wraps in { data: {...} }
|
||||
const data = json?.data ?? json ?? null;
|
||||
return NextResponse.json(data ?? {}, { status: 200 });
|
||||
} catch (err: any) {
|
||||
const msg = err?.message || "Failed to fetch current user";
|
||||
return NextResponse.json({ error: msg }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const BGBYE_URL =
|
||||
process.env.BGBYE_URL ||
|
||||
process.env.BG_BYE_URL ||
|
||||
process.env.BGREMOVER_BASE_URL ||
|
||||
"http://bgbye:7001";
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const r = await fetch(`${BGBYE_URL}/methods`, { cache: "no-store" });
|
||||
const body = await r.text();
|
||||
return new Response(body, {
|
||||
status: r.status,
|
||||
headers: { "content-type": r.headers.get("content-type") || "application/json" },
|
||||
});
|
||||
} catch {
|
||||
return new Response(JSON.stringify({ methods: [] }), {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
const BASE_DIR = '/app/files';
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const url = new URL(req.url);
|
||||
const raw = url.searchParams.get('path');
|
||||
if (!raw) {
|
||||
return NextResponse.json({ error: 'Missing path' }, { status: 400 });
|
||||
}
|
||||
const safe = path.normalize('/' + raw).replace(/^\/+/, '/');
|
||||
const target = path.resolve(BASE_DIR, '.' + safe);
|
||||
|
||||
if (!target.startsWith(BASE_DIR)) {
|
||||
return NextResponse.json({ error: 'Invalid path' }, { status: 400 });
|
||||
}
|
||||
|
||||
const st = await fs.stat(target).catch(() => null);
|
||||
if (!st || !st.isFile()) {
|
||||
return NextResponse.json({ error: 'Not a file' }, { status: 400 });
|
||||
}
|
||||
|
||||
const data = await fs.readFile(target);
|
||||
// naive content-type guess
|
||||
const ext = path.extname(target).toLowerCase();
|
||||
const ctype =
|
||||
ext === '.pdf' ? 'application/pdf' :
|
||||
ext === '.png' ? 'image/png' :
|
||||
ext === '.jpg' || ext === '.jpeg' ? 'image/jpeg' :
|
||||
ext === '.webp' ? 'image/webp' :
|
||||
ext === '.txt' ? 'text/plain; charset=utf-8' :
|
||||
'application/octet-stream';
|
||||
|
||||
return new Response(data, {
|
||||
headers: {
|
||||
'Content-Type': ctype,
|
||||
'Content-Length': String(data.byteLength),
|
||||
'Content-Disposition': `inline; filename="${path.basename(target)}"`,
|
||||
'Cache-Control': 'no-store',
|
||||
}
|
||||
});
|
||||
} catch (e: any) {
|
||||
return NextResponse.json({ error: e?.message ?? 'Unknown error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
const BASE = "/app/files";
|
||||
|
||||
function safeJoin(base: string, reqPath: string) {
|
||||
const rel = reqPath.startsWith("/") ? reqPath : `/${reqPath}`;
|
||||
const full = path.resolve(base, "." + rel);
|
||||
if (!full.startsWith(base)) throw new Error("Outside base");
|
||||
return full;
|
||||
}
|
||||
|
||||
const CONTENT_MAP: Record<string, string> = {
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".gif": "image/gif",
|
||||
".webp": "image/webp",
|
||||
".svg": "image/svg+xml",
|
||||
".txt": "text/plain; charset=utf-8",
|
||||
".json": "application/json; charset=utf-8",
|
||||
".pdf": "application/pdf",
|
||||
};
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const url = new URL(req.url);
|
||||
const reqPath = url.searchParams.get("path");
|
||||
if (!reqPath) return NextResponse.json({ error: "Missing path" }, { status: 400 });
|
||||
|
||||
const full = safeJoin(BASE, reqPath);
|
||||
const stat = await fs.stat(full);
|
||||
if (!stat.isFile()) return NextResponse.json({ error: "Not a file" }, { status: 400 });
|
||||
|
||||
const data = await fs.readFile(full);
|
||||
const ext = path.extname(full).toLowerCase();
|
||||
const type = CONTENT_MAP[ext] ?? "application/octet-stream";
|
||||
|
||||
return new NextResponse(data, {
|
||||
status: 200,
|
||||
headers: { "Content-Type": type, "Cache-Control": "public, max-age=300" },
|
||||
});
|
||||
} catch (e: any) {
|
||||
return NextResponse.json({ error: e?.message ?? "Unknown" }, { status: 400 });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
const BASE_DIR = '/app/files';
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const url = new URL(req.url);
|
||||
const raw = url.searchParams.get('path') ?? '/';
|
||||
const safe = path.normalize('/' + raw).replace(/^\/+/, '/'); // normalize & ensure leading slash
|
||||
const target = path.resolve(BASE_DIR, '.' + safe);
|
||||
|
||||
if (!target.startsWith(BASE_DIR)) {
|
||||
return NextResponse.json({ error: 'Invalid path' }, { status: 400 });
|
||||
}
|
||||
|
||||
const st = await fs.stat(target).catch(() => null);
|
||||
if (!st || !st.isDirectory()) {
|
||||
return NextResponse.json({ error: 'Not a directory' }, { status: 400 });
|
||||
}
|
||||
|
||||
const entries = await fs.readdir(target, { withFileTypes: true });
|
||||
const items = await Promise.all(entries.map(async (d) => {
|
||||
const full = path.join(target, d.name);
|
||||
const rel = path.posix.join(safe, d.name).replaceAll('\\', '/');
|
||||
const s = await fs.stat(full);
|
||||
return {
|
||||
name: d.name,
|
||||
path: rel,
|
||||
type: d.isDirectory() ? 'dir' : 'file',
|
||||
size: s.size,
|
||||
mtime: s.mtimeMs,
|
||||
};
|
||||
}));
|
||||
|
||||
return NextResponse.json({ path: safe, items });
|
||||
} catch (e: any) {
|
||||
return NextResponse.json({ error: e?.message ?? 'Unknown error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import fs from "node:fs/promises";
|
||||
import fssync from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const BASE = "/app/files"; // this is /var/www/makearmy.io/app/files on the host
|
||||
|
||||
function safeJoin(base: string, reqPath: string) {
|
||||
const decoded = decodeURIComponent(reqPath || "/");
|
||||
// normalize, strip traversal, and join under BASE
|
||||
const normalized = path.posix.normalize("/" + decoded).replace(/^(\.\.(\/|\\|$))+/g, "");
|
||||
const full = path.join(base, normalized);
|
||||
if (!full.startsWith(base)) throw new Error("Invalid path");
|
||||
return full;
|
||||
}
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const p = searchParams.get("path") || "/";
|
||||
const abs = safeJoin(BASE, p);
|
||||
|
||||
const entries = await fs.readdir(abs, { withFileTypes: true });
|
||||
const rows = await Promise.all(entries.map(async (ent) => {
|
||||
const full = path.join(abs, ent.name);
|
||||
const stat = await fs.stat(full);
|
||||
const isDir = ent.isDirectory();
|
||||
return {
|
||||
name: ent.name,
|
||||
type: isDir ? "dir" : "file",
|
||||
size: isDir ? null : stat.size,
|
||||
mtime: stat.mtime.toISOString(),
|
||||
path: path.posix.join(p.endsWith("/") ? p : p + "/", ent.name),
|
||||
// raw download/view URL (served by /api/files/raw)
|
||||
url: isDir ? null : `/api/files/raw?path=${encodeURIComponent(path.posix.join(p, ent.name))}`,
|
||||
};
|
||||
}));
|
||||
|
||||
// Sort: directories first, then files alphabetically
|
||||
rows.sort((a, b) => {
|
||||
if (a.type !== b.type) return a.type === "dir" ? -1 : 1;
|
||||
return a.name.localeCompare(b.name, undefined, { sensitivity: "base" });
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true, path: p, items: rows });
|
||||
} catch (err: any) {
|
||||
return NextResponse.json({ ok: false, error: err?.message || "Error" }, { status: 400 });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
// app/api/health/directus/route.ts
|
||||
import { NextResponse } from "next/server";
|
||||
import { directusFetch } from "@/lib/directus";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
export async function GET() {
|
||||
const out: any = { ok: true, checks: {} };
|
||||
try {
|
||||
// who am I?
|
||||
try {
|
||||
const who = await directusFetch<{ data: any }>(`/users/me?fields=id,email,role.name`);
|
||||
out.checks.user = { ok: true, role: who?.data?.role?.name ?? null };
|
||||
} catch (e: any) {
|
||||
out.checks.user = { ok: false, error: e?.message || String(e) };
|
||||
}
|
||||
|
||||
// can read folders?
|
||||
try {
|
||||
const folders = await directusFetch<{ data: any[] }>(`/folders?limit=1&fields=id,name`);
|
||||
out.checks.folders = { ok: true, sample: folders?.data?.[0] ?? null };
|
||||
} catch (e: any) {
|
||||
out.checks.folders = { ok: false, error: e?.message || String(e) };
|
||||
}
|
||||
|
||||
// can read files (not create; safe)
|
||||
try {
|
||||
const files = await directusFetch<{ data: any[] }>(`/files?limit=0`);
|
||||
out.checks.files_read = { ok: true, totalKnown: files?.data?.length ?? 0 };
|
||||
} catch (e: any) {
|
||||
out.checks.files_read = { ok: false, error: e?.message || String(e) };
|
||||
}
|
||||
|
||||
return NextResponse.json(out);
|
||||
} catch (e: any) {
|
||||
return NextResponse.json({ ok: false, error: e?.message || "health error", ...out }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// app/api/health/options/route.ts
|
||||
import { NextResponse } from "next/server";
|
||||
import { directusFetch } from "@/lib/directus";
|
||||
|
||||
const TESTS = [
|
||||
{ name: "material", path: "/items/material?limit=1" },
|
||||
{ name: "material_coating", path: "/items/material_coating?limit=1" },
|
||||
{ name: "material_color", path: "/items/material_color?limit=1" },
|
||||
{ name: "material_opacity", path: "/items/material_opacity?limit=1" },
|
||||
{ name: "laser_software", path: "/items/laser_software?limit=1" },
|
||||
{ name: "laser_source", path: "/items/laser_source?limit=1" },
|
||||
{ name: "laser_scan_lens", path: "/items/laser_scan_lens?limit=1" },
|
||||
{ name: "laser_focusing_lens",path: "/items/laser_focusing_lens?limit=1" },
|
||||
];
|
||||
|
||||
export async function GET() {
|
||||
const results: any[] = [];
|
||||
for (const t of TESTS) {
|
||||
try {
|
||||
const { data } = await directusFetch<{ data: any[] }>(t.path);
|
||||
const first = data?.[0] ?? null;
|
||||
results.push({ name: t.name, ok: true, sample_id: first?.submission_id ?? first?.id ?? null });
|
||||
} catch (e: any) {
|
||||
results.push({ name: t.name, ok: false, error: e?.message || String(e) });
|
||||
}
|
||||
}
|
||||
return NextResponse.json({ ok: true, results });
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// /var/www/makearmy.io/app/components/toolkit/ToolShell.tsx
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
|
||||
export default function ToolShell({
|
||||
title,
|
||||
subtitle,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="mx-auto max-w-4xl px-4 py-8 space-y-6">
|
||||
<header className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold">{title}</h1>
|
||||
{subtitle && (
|
||||
<p className="text-sm text-muted-foreground mt-1">{subtitle}</p>
|
||||
)}
|
||||
</div>
|
||||
<Link
|
||||
href="https://makearmy.io"
|
||||
className="rounded-lg px-3 py-2 border hover:bg-muted transition-colors text-sm"
|
||||
>
|
||||
Back to Main Menu
|
||||
</Link>
|
||||
</header>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { Suspense } from "react";
|
||||
import SettingsSubmit from "@/app/components/forms/SettingsSubmit";
|
||||
import SettingsSubmit from "@/components/forms/SettingsSubmit";
|
||||
|
||||
export const dynamic = "force-dynamic"; // keeps this page from being statically prerendered
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue