mirror of
https://github.com/Nezumi-2711/next-gdrive-index.git
synced 2026-09-22 20:01:36 +00:00
130 lines
3.2 KiB
TypeScript
130 lines
3.2 KiB
TypeScript
import gIndexConfig from "config";
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
|
|
import getSearchParams from "utils/apiHelper/getSearchParams";
|
|
import {
|
|
decryptData,
|
|
encryptData,
|
|
} from "utils/encryptionHelper/hash";
|
|
import ExtendedError from "utils/extendedError";
|
|
import gdrive from "utils/gdriveInstance";
|
|
|
|
import {
|
|
APIGetPasswordResponse,
|
|
ErrorResponse,
|
|
} from "types/api/response";
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const reqStart = Date.now();
|
|
|
|
try {
|
|
const { path } = getSearchParams(request.url, ["path"]);
|
|
if (!path)
|
|
throw new ExtendedError(
|
|
"Path is required",
|
|
400,
|
|
"Can't find path in query, please check your query",
|
|
);
|
|
const mappedPath: Record<
|
|
"name" | "id" | "mimeType",
|
|
string
|
|
>[] = JSON.parse(decryptData(path));
|
|
const passwordParents = mappedPath.map(
|
|
(path) => `'${decryptData(path.id)}' in parents`,
|
|
);
|
|
const query: string[] = [
|
|
"trashed = false",
|
|
`name = '${
|
|
gIndexConfig.apiConfig.specialFile.password
|
|
}' and (${passwordParents.join(" or ")})`,
|
|
];
|
|
const passwordData = await gdrive.files.list({
|
|
q: query.join(" and "),
|
|
fields: "files(id, name, parents)",
|
|
});
|
|
|
|
const protectedPaths = mappedPath.map((path) => {
|
|
const isPasswordExist = passwordData.data.files?.find(
|
|
(file) =>
|
|
file.parents?.[0] === decryptData(path.id),
|
|
);
|
|
if (isPasswordExist)
|
|
return {
|
|
name: path.name,
|
|
passwordId: isPasswordExist.id,
|
|
};
|
|
});
|
|
|
|
const _passwordContent: Promise<{
|
|
path: string;
|
|
password: string;
|
|
}>[] = [];
|
|
protectedPaths.forEach((path) => {
|
|
if (!path) return;
|
|
_passwordContent.push(
|
|
gdrive.files
|
|
.get(
|
|
{
|
|
fileId: path.passwordId as string,
|
|
alt: "media",
|
|
},
|
|
{ responseType: "text" },
|
|
)
|
|
.then((res) => ({
|
|
path: path.name as string,
|
|
password: res.data as string,
|
|
})),
|
|
);
|
|
});
|
|
|
|
const passwordContent = await Promise.all(
|
|
_passwordContent,
|
|
);
|
|
|
|
let prevPath = [""];
|
|
let password: Record<
|
|
"relativePath" | "password",
|
|
string
|
|
>[] = [];
|
|
|
|
mappedPath.forEach((path) => {
|
|
prevPath.push(path.name);
|
|
const isPasswordExist = passwordContent.find(
|
|
(password) => password.path === path.name,
|
|
);
|
|
if (isPasswordExist) {
|
|
password.push({
|
|
relativePath: prevPath.join("/"),
|
|
password: encryptData(isPasswordExist.password),
|
|
});
|
|
}
|
|
});
|
|
|
|
const payload: APIGetPasswordResponse = {
|
|
timestamp: Date.now(),
|
|
responseTime: Date.now() - reqStart,
|
|
data: password,
|
|
};
|
|
|
|
return NextResponse.json(payload, {
|
|
status: 200,
|
|
headers: {
|
|
"Cache-Control": gIndexConfig.cacheControl,
|
|
},
|
|
});
|
|
} catch (error: any) {
|
|
const res: ErrorResponse = {
|
|
timestamp: Date.now(),
|
|
responseTime: Date.now() - reqStart,
|
|
error: {
|
|
code: error.code || 500,
|
|
message: error.message,
|
|
reason: error.errors?.[0].reason,
|
|
},
|
|
};
|
|
return NextResponse.json(res, {
|
|
status: error.code || 500,
|
|
});
|
|
}
|
|
}
|