cos tam dziala

This commit is contained in:
Patryk Koreń
2026-07-06 23:17:37 +02:00
parent e7ec832f5b
commit ff707dd762
26 changed files with 494 additions and 60 deletions

35
back/src/lib/crateClip.ts Normal file
View File

@@ -0,0 +1,35 @@
import { execa } from "execa";
import ffmpegPath from "ffmpeg-static";
import path from "node:path";
export async function encodeFrames({
inputPattern,
output,
fps = 30,
}: {
inputPattern: string;
output: string;
fps?: number;
}) {
console.log("kleje filmik");
await execa(ffmpegPath!, [
"-y",
"-pattern_type", "glob",
"-framerate", fps.toString(),
"-i", inputPattern,
"-i", path.resolve("./music.mp3"),
"-c:v", "libx264",
"-pix_fmt", "yuv420p",
"-c:a", "mp3",
"-shortest",
// "-preset", "medium",
// "-crf", "18",
output,
]);
console.log("filmik sklejony");
}

62
back/src/lib/nextcloud.ts Normal file
View File

@@ -0,0 +1,62 @@
import { createClient, type BufferLike } from "webdav";
import fs from "fs/promises";
import path from "path";
export const REMOTE_DIR = "/";
export const LOCAL_DIR = path.resolve("./downloads");
export async function downloadMissing(remoteDir: string = REMOTE_DIR) {
await fs.mkdir(LOCAL_DIR, { recursive: true })
const client = createClient(
"https://nextcloud.papryk.com/public.php/dav/files/ckkL3Pg4X4Ye6pz",
{
username: "ckkL3Pg4X4Ye6pz",
password: "",
}
);
const contents = await client.getDirectoryContents(remoteDir);
const exisitngFiles = await fs.readdir(LOCAL_DIR);
const missing = contents.filter(f => !exisitngFiles.includes(f.basename))
console.log(missing)
let i = 0;
for (const item of missing) {
const result = await client.getFileContents(item.filename, {
format: "binary",
});
let buffer: Buffer;
if (typeof result === "string") {
buffer = Buffer.from(result);
} else if (Buffer.isBuffer(result)) {
buffer = result;
} else if (result instanceof ArrayBuffer) {
buffer = Buffer.from(new Uint8Array(result));
} else if ("data" in result) {
const data = result.data;
if (typeof data === "string") {
buffer = Buffer.from(data);
} else if (Buffer.isBuffer(data)) {
buffer = data;
} else if (data instanceof ArrayBuffer) {
buffer = Buffer.from(new Uint8Array(data));
} else {
buffer = Buffer.from(data as any);
}
} else {
buffer = Buffer.from(result as any);
}
const localPath = path.resolve(path.join(LOCAL_DIR, item.filename))
await fs.writeFile(localPath, buffer);
i++;
console.log(`downloaded ${i}/${missing.length} ${item.basename}`)
}
}

View File

@@ -2,21 +2,31 @@ import jwt from "jsonwebtoken";
import type { Request, Response, NextFunction } from "express";
export function authMiddleware(req: Request, res: Response, next: NextFunction) {
const header = req.headers.authorization;
const error = "You must be logged in to access this page"
// const header = req.headers.authorization;
// const error = "You must be logged in to access this page"
if (!header) {
return res.status(401).json({ error });
}
// if (!header) {
// return res.status(401).json({ error });
// }
const token = header.split(" ")[1]; // "Bearer TOKEN"
// const token = header.split(" ")[1]; // "Bearer TOKEN"
// try {
// if (!token) throw new Error("No Bearer Token")
// const decoded = jwt.verify(token, process.env.JWT_SECRET!);
// (req as any).user = decoded;
// next();
// } catch (err) {
// return res.status(401).json({ error });
// }
const token = req.cookies.token;
if (!token) return res.sendStatus(401);
try {
if (!token) throw new Error("No Bearer Token")
const decoded = jwt.verify(token, process.env.JWT_SECRET!);
(req as any).user = decoded;
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as jwt.JwtPayload;
req.user = decoded;
next();
} catch (err) {
return res.status(401).json({ error });
} catch {
res.sendStatus(403);
}
}

View File

@@ -20,8 +20,14 @@ router.post("/login", async (req, res) => {
{ expiresIn: "1h" }
);
res.cookie("token", token, {
httpOnly: true, // cannot be accessed by JS (important security)
secure: false, // set true in production (HTTPS)
sameSite: "lax", // or "none" if cross-site HTTPS
maxAge: 60 * 60 * 1000,
});
res.json({
token,
user,
});
} catch (err: any) {

View File

@@ -1,12 +1,36 @@
// src/routes/auth.ts
import { Router } from "express";
import { downloadMissing, LOCAL_DIR } from "../lib/nextcloud";
import path from "node:path";
import { encodeFrames } from "../lib/crateClip";
const router = Router();
router.get("/video", async (req, res) => {
res.json({
tajne: "XD"
});
const videoPath = path.resolve("./out.mp4");
res.sendFile(videoPath);
});
router.post("/createclip", async (req, res) => {
try {
encodeFrames({
inputPattern: `${LOCAL_DIR}/*.jpg`,
output: path.resolve("./out.mp4"),
fps: 12,
});
res.end(200);
} catch {
res.end(501);
}
})
router.post("/refreshfiles", async (req, res) => {
try {
await downloadMissing();
res.end(200);
} catch {
res.end(501);
}
})
export default router;

View File

@@ -5,6 +5,7 @@ import authRoutes from "./routes/auth";
import protectedRoutes from "./routes/protected";
import cors from "cors";
import { authMiddleware } from "./middleware/auth";
import cookieParser from "cookie-parser";
dotenv.config();
@@ -17,6 +18,7 @@ app.use(cors({
}));
app.use(express.json());
app.use(cookieParser())
app.use("/auth", authRoutes);
app.use("/protected", authMiddleware, protectedRoutes);

12
back/src/types/express.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
import "express";
declare module "express-serve-static-core" {
interface Request {
user?: {
sub: string;
username: string;
iat?: number;
exp?: number;
} | string | jwt.JwtPayload;
}
}