mirror of
				https://github.com/kyantech/Palmr.git
				synced 2025-11-04 05:53:23 +00:00 
			
		
		
		
	Compare commits
	
		
			6 Commits
		
	
	
		
			v3.0.0-bet
			...
			v3.0.0-bet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					98586efbcd | ||
| 
						 | 
					c724e644c7 | ||
| 
						 | 
					555ff18a87 | ||
| 
						 | 
					5100e1591b | ||
| 
						 | 
					6de29bbf07 | ||
| 
						 | 
					39c47be940 | 
@@ -4,7 +4,21 @@ import { FastifyReply, FastifyRequest } from "fastify";
 | 
			
		||||
import fs from "fs";
 | 
			
		||||
import path from "path";
 | 
			
		||||
 | 
			
		||||
const uploadsDir = path.join(process.cwd(), "uploads/logo");
 | 
			
		||||
const isDocker = (() => {
 | 
			
		||||
  try {
 | 
			
		||||
    require("fs").statSync("/.dockerenv");
 | 
			
		||||
    return true;
 | 
			
		||||
  } catch {
 | 
			
		||||
    try {
 | 
			
		||||
      return require("fs").readFileSync("/proc/self/cgroup", "utf8").includes("docker");
 | 
			
		||||
    } catch {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
const baseDir = isDocker ? "/app/server" : process.cwd();
 | 
			
		||||
const uploadsDir = path.join(baseDir, "uploads/logo");
 | 
			
		||||
if (!fs.existsSync(uploadsDir)) {
 | 
			
		||||
  fs.mkdirSync(uploadsDir, { recursive: true });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import { env } from "../../env";
 | 
			
		||||
import { LoginSchema, RequestPasswordResetSchema, createResetPasswordSchema } from "./dto";
 | 
			
		||||
import { AuthService } from "./service";
 | 
			
		||||
import { env } from "env";
 | 
			
		||||
import { FastifyReply, FastifyRequest } from "fastify";
 | 
			
		||||
 | 
			
		||||
export class AuthController {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { env } from "../../env";
 | 
			
		||||
import { ConfigService } from "../config/service";
 | 
			
		||||
import { env } from "env";
 | 
			
		||||
import nodemailer from "nodemailer";
 | 
			
		||||
 | 
			
		||||
export class EmailService {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ export async function userRoutes(app: FastifyInstance) {
 | 
			
		||||
      const usersCount = await prisma.user.count();
 | 
			
		||||
 | 
			
		||||
      if (usersCount > 0) {
 | 
			
		||||
        try {
 | 
			
		||||
          await request.jwtVerify();
 | 
			
		||||
          if (!request.user.isAdmin) {
 | 
			
		||||
            return reply
 | 
			
		||||
@@ -21,14 +22,19 @@ export async function userRoutes(app: FastifyInstance) {
 | 
			
		||||
              .send({ error: "Access restricted to administrators" })
 | 
			
		||||
              .description("Access restricted to administrators");
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      console.error(err);
 | 
			
		||||
        } catch (authErr) {
 | 
			
		||||
          console.error(authErr);
 | 
			
		||||
          return reply
 | 
			
		||||
            .status(401)
 | 
			
		||||
            .send({ error: "Unauthorized: a valid token is required to access this resource." })
 | 
			
		||||
            .description("Unauthorized: a valid token is required to access this resource.");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // If usersCount is 0, allow the request to proceed without authentication
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      console.error(err);
 | 
			
		||||
      return reply.status(500).send({ error: "Internal server error" }).description("Internal server error");
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const createRegisterSchema = async () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,16 +9,31 @@ import { pipeline } from "stream/promises";
 | 
			
		||||
 | 
			
		||||
export class FilesystemStorageProvider implements StorageProvider {
 | 
			
		||||
  private static instance: FilesystemStorageProvider;
 | 
			
		||||
  private uploadsDir = path.join(process.cwd(), "uploads");
 | 
			
		||||
  private uploadsDir: string;
 | 
			
		||||
  private encryptionKey = env.ENCRYPTION_KEY;
 | 
			
		||||
  private uploadTokens = new Map<string, { objectName: string; expiresAt: number }>();
 | 
			
		||||
  private downloadTokens = new Map<string, { objectName: string; expiresAt: number; fileName?: string }>();
 | 
			
		||||
 | 
			
		||||
  private constructor() {
 | 
			
		||||
    this.uploadsDir = this.isDocker() ? "/app/server/uploads" : path.join(process.cwd(), "uploads");
 | 
			
		||||
 | 
			
		||||
    this.ensureUploadsDir();
 | 
			
		||||
    setInterval(() => this.cleanExpiredTokens(), 5 * 60 * 1000);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private isDocker(): boolean {
 | 
			
		||||
    try {
 | 
			
		||||
      fsSync.statSync("/.dockerenv");
 | 
			
		||||
      return true;
 | 
			
		||||
    } catch {
 | 
			
		||||
      try {
 | 
			
		||||
        return fsSync.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
 | 
			
		||||
      } catch {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static getInstance(): FilesystemStorageProvider {
 | 
			
		||||
    if (!FilesystemStorageProvider.instance) {
 | 
			
		||||
      FilesystemStorageProvider.instance = new FilesystemStorageProvider();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ import { storageRoutes } from "./modules/storage/routes";
 | 
			
		||||
import { userRoutes } from "./modules/user/routes";
 | 
			
		||||
import fastifyMultipart from "@fastify/multipart";
 | 
			
		||||
import fastifyStatic from "@fastify/static";
 | 
			
		||||
import * as fsSync from "fs";
 | 
			
		||||
import * as fs from "fs/promises";
 | 
			
		||||
import crypto from "node:crypto";
 | 
			
		||||
import path from "path";
 | 
			
		||||
@@ -26,21 +27,36 @@ if (typeof global.crypto === "undefined") {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function ensureDirectories() {
 | 
			
		||||
  const uploadsDir = path.join(process.cwd(), "uploads");
 | 
			
		||||
  const tempChunksDir = path.join(process.cwd(), "temp-chunks");
 | 
			
		||||
  // Use /app/server paths in Docker, current directory for local development
 | 
			
		||||
  const isDocker = (() => {
 | 
			
		||||
    try {
 | 
			
		||||
      fsSync.statSync("/.dockerenv");
 | 
			
		||||
      return true;
 | 
			
		||||
    } catch {
 | 
			
		||||
      try {
 | 
			
		||||
        return fsSync.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
 | 
			
		||||
      } catch {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })();
 | 
			
		||||
 | 
			
		||||
  const baseDir = isDocker ? "/app/server" : process.cwd();
 | 
			
		||||
  const uploadsDir = path.join(baseDir, "uploads");
 | 
			
		||||
  const tempChunksDir = path.join(baseDir, "temp-chunks");
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    await fs.access(uploadsDir);
 | 
			
		||||
  } catch {
 | 
			
		||||
    await fs.mkdir(uploadsDir, { recursive: true });
 | 
			
		||||
    console.log("📁 Created uploads directory");
 | 
			
		||||
    console.log(`📁 Created uploads directory: ${uploadsDir}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    await fs.access(tempChunksDir);
 | 
			
		||||
  } catch {
 | 
			
		||||
    await fs.mkdir(tempChunksDir, { recursive: true });
 | 
			
		||||
    console.log("📁 Created temp-chunks directory");
 | 
			
		||||
    console.log(`📁 Created temp-chunks directory: ${tempChunksDir}`);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -62,8 +78,24 @@ async function startServer() {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (env.ENABLE_S3 !== "true") {
 | 
			
		||||
    const isDocker = (() => {
 | 
			
		||||
      try {
 | 
			
		||||
        fsSync.statSync("/.dockerenv");
 | 
			
		||||
        return true;
 | 
			
		||||
      } catch {
 | 
			
		||||
        try {
 | 
			
		||||
          return fsSync.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
 | 
			
		||||
        } catch {
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    })();
 | 
			
		||||
 | 
			
		||||
    const baseDir = isDocker ? "/app/server" : process.cwd();
 | 
			
		||||
    const uploadsPath = path.join(baseDir, "uploads");
 | 
			
		||||
 | 
			
		||||
    await app.register(fastifyStatic, {
 | 
			
		||||
      root: path.join(process.cwd(), "uploads"),
 | 
			
		||||
      root: uploadsPath,
 | 
			
		||||
      prefix: "/uploads/",
 | 
			
		||||
      decorateReply: false,
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -3,12 +3,15 @@ import { NextRequest, NextResponse } from "next/server";
 | 
			
		||||
export async function POST(req: NextRequest, { params }: { params: Promise<{ shareId: string }> }) {
 | 
			
		||||
  const cookieHeader = req.headers.get("cookie");
 | 
			
		||||
  const { shareId } = await params;
 | 
			
		||||
  const body = await req.text();
 | 
			
		||||
 | 
			
		||||
  const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${shareId}/recipients/notify`, {
 | 
			
		||||
  const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${shareId}/notify`, {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    headers: {
 | 
			
		||||
      "Content-Type": "application/json",
 | 
			
		||||
      cookie: cookieHeader || "",
 | 
			
		||||
    },
 | 
			
		||||
    body: body,
 | 
			
		||||
    redirect: "manual",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user