Skip to content

Commit

Permalink
feat: Add demo mode & fix: Some appearance bug & docs: Change README
Browse files Browse the repository at this point in the history
  • Loading branch information
NriotHrreion committed Aug 9, 2024
1 parent 4df7cde commit ee7a43d
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 18 deletions.
4 changes: 1 addition & 3 deletions .pwd.example
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# Default password: 123456
# Remember to change this password after setting up the app
PASSWORD=14e1b600b1fd579f47433b88e8d85291
PASSWORD=14e1b600b1fd579f47433b88e8d85291
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ First, you need to make sure that your server (or computer) has installed Nodejs
git clone https://github.com/nocpiun/ferrum.git
cd ferrum
npm i
npm run patch
npm run build
```

2. Prepare the `.pwd` file

Rename the `.pwd.example` to `.pwd` in the project root folder. And delete the comments in it. This file stores your access key to Ferrum. The default password is `123456`, and you can change your password in the settings.
Rename the `.pwd.example` to `.pwd` in the project root folder. This file stores your access key to Ferrum. The default password is `123456`, and you can change your password in the settings.

```txt
PASSWORD=....
Expand Down Expand Up @@ -102,6 +103,7 @@ An explanation of the `package.json` scripts.

- **`start`** Launch the app in production mode
- **`dev`** Launch the app in development mode
- **`patch`** Install `next-ws` plugin
- **`build`** Create a production build
- **`build:ci`** Create a production build for CI environment
- **`lint`** Run ESLint
Expand Down
4 changes: 2 additions & 2 deletions app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useRouter } from "next/navigation";
import ThemeSwitch from "@/components/theme-switch";
import PasswordInput from "@/components/password-input";
import { BaseResponseData } from "@/types";
import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";

const schema = z.object({
password: z.string().min(6, { message: "请输入访问密码" }),
Expand Down Expand Up @@ -85,7 +85,7 @@ export default function Page() {
src="/icon.png"
className="w-[70px] mb-4"
style={{ imageRendering: "pixelated" }}/>
<h1 className="font-bold text-2xl mb-2">登录 Ferrum</h1>
<h1 className="font-bold text-2xl mb-2">登录 Ferrum{isDemo ? " (Demo)" : ""}</h1>
<p className="text-default-400 text-sm">Explore throughout your server.</p>
</div>

Expand Down
17 changes: 15 additions & 2 deletions app/api/fs/disks/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,25 @@ import os from "node:os";
import { NextRequest } from "next/server";
import si from "systeminformation";

import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
import { packet, error } from "@/lib/packet";
// Demo
import demoOS from "@/lib/demo/os.json";

export async function GET(req: NextRequest) {
if(isDemo) {
return packet({
system: demoOS.os.platform,
disks: demoOS.disk.map((item) => ({
used: item.used,
size: item.size,
capacity: (item.used / item.size) * 100,
mount: item.mount
}))
});
}

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand All @@ -17,7 +31,6 @@ export async function GET(req: NextRequest) {
const disk = await si.fsSize();

return packet({
status: 200,
system: os.platform(),
disks: disk.map((item) => ({
used: item.used,
Expand Down
15 changes: 14 additions & 1 deletion app/api/fs/download/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@ import path from "node:path";
import { NextRequest, NextResponse } from "next/server";
import mime from "mime";

import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
import { error } from "@/lib/packet";
import { streamFile } from "@/lib/stream";
// Demo
import demoFile from "@/lib/demo/file.json";

export async function GET(req: NextRequest) {
if(isDemo) {
return new NextResponse(demoFile.content, {
status: 200,
headers: {
"Content-Disposition": `attachment; filename=hello.txt`,
"Content-Type": "text/plain",
"Content-Length": demoFile.size.toString()
}
});
}

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down
14 changes: 13 additions & 1 deletion app/api/fs/file/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import path from "node:path";
import { NextRequest, NextResponse } from "next/server";
import mime from "mime";

import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
import { packet, error } from "@/lib/packet";
import { streamFile } from "@/lib/stream";
import { getFileType } from "@/lib/utils";
// Demo
import demoFile from "@/lib/demo/file.json";

export async function GET(req: NextRequest) {
if(isDemo) {
return packet(demoFile);
}

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down Expand Up @@ -59,6 +65,8 @@ interface FilePostRequestData {
}

export async function POST(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down Expand Up @@ -95,6 +103,8 @@ interface FilePatchRequestData {
}

export async function PATCH(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down Expand Up @@ -125,6 +135,8 @@ export async function PATCH(req: NextRequest) {
}

export async function DELETE(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down
16 changes: 15 additions & 1 deletion app/api/fs/folder/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ import path from "node:path";

import { NextRequest } from "next/server";

import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
import { packet, error } from "@/lib/packet";
// Demo
import demoFiles from "@/lib/demo/files.json";

export async function GET(req: NextRequest) {
if(isDemo) {
return packet({
items: demoFiles
});
}

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down Expand Up @@ -62,6 +70,8 @@ interface FolderPostRequestData {
}

export async function POST(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down Expand Up @@ -95,6 +105,8 @@ export async function POST(req: NextRequest) {
}

export async function DELETE(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down Expand Up @@ -128,6 +140,8 @@ interface FolderPutRequestData {
}

export async function PUT(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down
6 changes: 4 additions & 2 deletions app/api/fs/thumbnail/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import fs from "node:fs";
import { NextRequest, NextResponse } from "next/server";
import mime from "mime";

import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
import { error } from "@/lib/packet";
import { error, packet } from "@/lib/packet";
import { getExtname, getFileType } from "@/lib/utils";
import { streamFile } from "@/lib/stream";

export async function GET(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down
4 changes: 3 additions & 1 deletion app/api/fs/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import path from "node:path";

import { NextRequest } from "next/server";

import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
import { packet, error } from "@/lib/packet";

export async function POST(req: NextRequest) {
if(isDemo) return packet({});

const token = req.cookies.get(tokenStorageKey)?.value;

if(!token) return error(401);
Expand Down
10 changes: 9 additions & 1 deletion app/api/os/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { cpuModel, usagePercent as cpuPercent } from "node-system-stats";
import cookie from "cookie";

import { error } from "@/lib/packet";
import { tokenStorageKey } from "@/lib/global";
import { isDemo, tokenStorageKey } from "@/lib/global";
import { validateToken } from "@/lib/token";
// Demo
import demoOS from "@/lib/demo/os.json";

export function GET() {
return error(400);
Expand All @@ -38,6 +40,12 @@ export function SOCKET(
console.log("[Server: /api/os] Socket client connected.");

const handleRequest = async () => {
if(isDemo) {
client.send(JSON.stringify(demoOS));

return;
}

const cpu = await si.cpu();
const cpuTemp = await si.cpuTemperature();
const mem = await si.mem();
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/disk-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const DiskWidget: React.FC<PropsWithCN> = (props) => {
<HardDrive size={20} className="stroke-default-400"/>

<div className="flex-1 flex justify-between items-end">
<span className="text-lg font-semibold">
<span className="text-lg font-semibold overflow-hidden text-ellipsis whitespace-nowrap">
{disk.mount}
</span>

Expand Down
2 changes: 1 addition & 1 deletion components/explorer/disk-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const DiskItem: React.FC<DiskItemProps> = (props) => {
return (
<div className="w-40 flex flex-col gap-1">
<div className="flex justify-between items-end">
<span className="font-semibold">{props.mount}</span>
<span className="font-semibold overflow-hidden text-ellipsis whitespace-nowrap">{props.mount}</span>
<span className="text-xs text-default-500">
{formatSize(props.used, 1)} / {formatSize(props.size, 1)}
</span>
Expand Down
7 changes: 7 additions & 0 deletions lib/auth.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import fs from "fs";
import path from "path";

import { isDemo } from "./global";

const envPath = path.join(process.cwd(), ".pwd");
const defaultPwd = "14e1b600b1fd579f47433b88e8d85291"; // 123456

export function getPasswordFromEnv(): string {
if(isDemo) return defaultPwd;

const env = fs.readFileSync(envPath, "utf-8");

return env.replace("PASSWORD=", "");
}

export function setPasswordToEnv(password: string) {
if(isDemo) return;

fs.writeFileSync(envPath, `PASSWORD=${password}`, "utf-8");
}
5 changes: 5 additions & 0 deletions lib/demo/file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"path": "hello.txt",
"size": 53,
"content": "Welcome to Ferrum Explorer. This is a DEMO text file."
}
20 changes: 20 additions & 0 deletions lib/demo/files.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"name": "hello.txt",
"type": "file",
"size": 53,
"access": true
},
{
"name": "test.txt",
"type": "file",
"size": 1024,
"access": true
},
{
"name": "demo-folder",
"type": "folder",
"size": 0,
"access": true
}
]
Loading

0 comments on commit ee7a43d

Please sign in to comment.