mirror of
https://github.com/Nezumi-2711/next-gdrive-index.git
synced 2026-09-22 13:38:38 +00:00
Fix showing wrong content
This commit is contained in:
+76
-101
@@ -4,14 +4,14 @@ import crypto from "crypto";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { cookies } from "next/headers";
|
||||
import { z } from "zod";
|
||||
import { Schema_File } from "~/schema";
|
||||
|
||||
import { decryptData, encryptData } from "~/utils/encryptionHelper/hash";
|
||||
import { decryptData, encryptData } from "~/utils/encryptionHelper";
|
||||
import gdrive, { gdriveNoCache } from "~/utils/gdriveInstance";
|
||||
|
||||
import { Constant } from "~/types/constant";
|
||||
import { Schema_File } from "~/types/schema";
|
||||
|
||||
import config from "~/config/gIndex.config";
|
||||
import config from "config";
|
||||
|
||||
export async function CheckSitePassword(): Promise<{
|
||||
success: boolean;
|
||||
@@ -36,9 +36,7 @@ export async function CheckSitePassword(): Promise<{
|
||||
const password = store.get(Constant.cookies_SitePassword)?.value || "";
|
||||
const decryptedPassword = await decryptData(password);
|
||||
if (decryptedPassword !== process.env.SITE_PASSWORD)
|
||||
throw new Error(
|
||||
"Saved password is incorrect, please re-enter the password",
|
||||
);
|
||||
throw new Error("Saved password is incorrect, please re-enter the password");
|
||||
|
||||
return {
|
||||
success: true,
|
||||
@@ -156,32 +154,58 @@ export async function CheckPaths(paths: string[]): Promise<
|
||||
|
||||
const data = await Promise.all(promises);
|
||||
const notFoundIndex = data.findIndex((item) => !item);
|
||||
if (notFoundIndex !== -1)
|
||||
throw new Error(`Path not found: ${paths[notFoundIndex]}`);
|
||||
if (notFoundIndex !== -1) throw new Error(`Path not found: ${paths[notFoundIndex]}`);
|
||||
|
||||
// Check if each path is valid
|
||||
let valid = true;
|
||||
let invalidPath: string | undefined;
|
||||
const decryptedRootId = await decryptData(config.apiConfig.rootFolder);
|
||||
for (const [index, path] of data.entries()) {
|
||||
const dataWithIndex = data.map((item, index) => {
|
||||
return {
|
||||
...item,
|
||||
index: index,
|
||||
};
|
||||
});
|
||||
const filteredPaths: { path: string; data: { id: string; parents: string; mimeType: string }[] }[] = [];
|
||||
|
||||
for (const item of dataWithIndex) {
|
||||
if (!valid) break;
|
||||
|
||||
if (index === 0) {
|
||||
if (
|
||||
path?.data[0].parents === decryptedRootId ||
|
||||
path?.data[0].parents === decryptedSharedDrive
|
||||
)
|
||||
break;
|
||||
} else {
|
||||
if (path?.data[0].parents === data[index - 1]?.data[0].id) break;
|
||||
// Loop through data
|
||||
// If the current index is 0, check if the parents is the root folder or shared drive
|
||||
// If the current index is not 0, check if the parents is the previous data id from the filteredPaths
|
||||
|
||||
// Use filteredPaths because it will only contain the valid path
|
||||
// So if filteredPaths length is not equal to paths length, then it means there is an invalid path
|
||||
for (const path of item.data || []) {
|
||||
if (item.index === 0) {
|
||||
if (path.parents === decryptedRootId || path.parents === decryptedSharedDrive) {
|
||||
filteredPaths.push({
|
||||
path: item.path!,
|
||||
data: [{ id: path.id!, parents: path.parents!, mimeType: path.mimeType! }],
|
||||
});
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (path.parents === filteredPaths[item.index - 1]?.data?.[0].id) {
|
||||
filteredPaths.push({
|
||||
path: item.path!,
|
||||
data: [{ id: path.id!, parents: path.parents!, mimeType: path.mimeType! }],
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
valid = false;
|
||||
invalidPath = data[index]?.path;
|
||||
}
|
||||
if (filteredPaths.length !== paths.length) {
|
||||
valid = false;
|
||||
invalidPath = dataWithIndex[filteredPaths.length]?.path;
|
||||
}
|
||||
|
||||
if (!valid) throw new Error(`Invalid path: ${invalidPath}`);
|
||||
|
||||
const ids: { path: string; id: string }[] = [];
|
||||
for (const item of data) {
|
||||
for (const item of filteredPaths) {
|
||||
if (item) {
|
||||
const encryptedId = await encryptData(item.data[0].id as string);
|
||||
ids.push({
|
||||
@@ -203,9 +227,7 @@ export async function CheckPaths(paths: string[]): Promise<
|
||||
};
|
||||
}
|
||||
}
|
||||
export async function CheckPassword(
|
||||
paths: { path: string; id: string }[],
|
||||
): Promise<
|
||||
export async function CheckPassword(paths: { path: string; id: string }[]): Promise<
|
||||
| {
|
||||
success: false;
|
||||
message?: string;
|
||||
@@ -250,21 +272,15 @@ export async function CheckPassword(
|
||||
// To save processing time, skip if password file not found
|
||||
if (!password.files?.length) return { success: true };
|
||||
|
||||
const protectedFolder = password.files
|
||||
.filter((file) => ids.includes(file.parents?.[0] as string))
|
||||
?.shift(); // Shift to get only the nearest folder
|
||||
const protectedFolder = password.files.filter((file) => ids.includes(file.parents?.[0] as string))?.shift(); // Shift to get only the nearest folder
|
||||
|
||||
// To save processing time, skip if all of the paths are not protected
|
||||
if (!protectedFolder) return { success: true };
|
||||
|
||||
const store = cookies();
|
||||
const folderIndex = ids.findIndex(
|
||||
(item) => item === protectedFolder.parents?.[0],
|
||||
);
|
||||
const folderIndex = ids.findIndex((item) => item === protectedFolder.parents?.[0]);
|
||||
|
||||
const cookiesValue = JSON.parse(
|
||||
store.get(Constant.cookies_FolderPassword)?.value || "{}",
|
||||
);
|
||||
const cookiesValue = JSON.parse(store.get(Constant.cookies_FolderPassword)?.value || "{}");
|
||||
const currentFolder = paths[folderIndex];
|
||||
if (!cookiesValue[currentFolder.id])
|
||||
throw {
|
||||
@@ -321,9 +337,7 @@ export async function SetPassword(
|
||||
}> {
|
||||
try {
|
||||
const store = cookies();
|
||||
const cookiesValue = JSON.parse(
|
||||
store.get(Constant.cookies_FolderPassword)?.value || "{}",
|
||||
);
|
||||
const cookiesValue = JSON.parse(store.get(Constant.cookies_FolderPassword)?.value || "{}");
|
||||
const updatedValue = {
|
||||
...cookiesValue,
|
||||
[path]: await encryptData(password),
|
||||
@@ -352,13 +366,7 @@ export async function SetPassword(
|
||||
}
|
||||
}
|
||||
|
||||
export async function GetFiles({
|
||||
id,
|
||||
pageToken,
|
||||
}: {
|
||||
id?: string;
|
||||
pageToken?: string;
|
||||
}): Promise<{
|
||||
export async function GetFiles({ id, pageToken }: { id?: string; pageToken?: string }): Promise<{
|
||||
files: z.infer<typeof Schema_File>[];
|
||||
nextPageToken?: string;
|
||||
}> {
|
||||
@@ -372,14 +380,10 @@ export async function GetFiles({
|
||||
decryptedSharedDrive = await decryptData(config.apiConfig.sharedDrive);
|
||||
}
|
||||
|
||||
const filterName = config.apiConfig.hiddenFiles
|
||||
.map((item) => `not name = '${item}'`)
|
||||
.join(" and ");
|
||||
const query: string = [
|
||||
...config.apiConfig.defaultQuery,
|
||||
`'${decryptedId}' in parents`,
|
||||
`${filterName}`,
|
||||
].join(" and ");
|
||||
const filterName = config.apiConfig.hiddenFiles.map((item) => `not name = '${item}'`).join(" and ");
|
||||
const query: string = [...config.apiConfig.defaultQuery, `'${decryptedId}' in parents`, `${filterName}`].join(
|
||||
" and ",
|
||||
);
|
||||
|
||||
const data = await gdrive.files.list({
|
||||
q: query,
|
||||
@@ -396,21 +400,16 @@ export async function GetFiles({
|
||||
});
|
||||
|
||||
const encryptedData: z.infer<typeof Schema_File>[] = [];
|
||||
if (!data.data.files?.length)
|
||||
return { files: [], nextPageToken: undefined };
|
||||
if (!data.data.files?.length) return { files: [], nextPageToken: undefined };
|
||||
for (const file of data.data.files) {
|
||||
encryptedData.push({
|
||||
mimeType: file.mimeType as string,
|
||||
encryptedId: await encryptData(file.id as string),
|
||||
name: file.name as string,
|
||||
trashed: (file.trashed as boolean) ?? false,
|
||||
modifiedTime: new Date(
|
||||
file.modifiedTime as string,
|
||||
).toLocaleDateString(),
|
||||
modifiedTime: new Date(file.modifiedTime as string).toLocaleDateString(),
|
||||
fileExtension: file.fileExtension || undefined,
|
||||
encryptedWebContentLink: file.webContentLink
|
||||
? await encryptData(file.webContentLink)
|
||||
: undefined,
|
||||
encryptedWebContentLink: file.webContentLink ? await encryptData(file.webContentLink) : undefined,
|
||||
size: file.size ? Number(file.size) : undefined,
|
||||
thumbnailLink: file.thumbnailLink || undefined,
|
||||
imageMediaMetadata: file.imageMediaMetadata
|
||||
@@ -441,9 +440,7 @@ export async function GetFiles({
|
||||
throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
export async function GetFile(
|
||||
encryptedId: string,
|
||||
): Promise<z.infer<typeof Schema_File>> {
|
||||
export async function GetFile(encryptedId: string): Promise<z.infer<typeof Schema_File>> {
|
||||
try {
|
||||
const decryptedId = await decryptData(encryptedId);
|
||||
const { data: file } = await gdrive.files.get({
|
||||
@@ -459,9 +456,7 @@ export async function GetFile(
|
||||
trashed: (file.trashed as boolean) ?? false,
|
||||
modifiedTime: new Date(file.modifiedTime as string).toLocaleDateString(),
|
||||
fileExtension: file.fileExtension || undefined,
|
||||
encryptedWebContentLink: file.webContentLink
|
||||
? await encryptData(file.webContentLink)
|
||||
: undefined,
|
||||
encryptedWebContentLink: file.webContentLink ? await encryptData(file.webContentLink) : undefined,
|
||||
size: file.size ? Number(file.size) : undefined,
|
||||
thumbnailLink: file.thumbnailLink || undefined,
|
||||
imageMediaMetadata: file.imageMediaMetadata
|
||||
@@ -504,9 +499,7 @@ export async function SearchFile(
|
||||
const query: string[] = [
|
||||
...config.apiConfig.defaultQuery,
|
||||
`name contains '${keyword}'`,
|
||||
config.apiConfig.hiddenFiles
|
||||
.map((item) => `not name = '${item}'`)
|
||||
.join(" and "),
|
||||
config.apiConfig.hiddenFiles.map((item) => `not name = '${item}'`).join(" and "),
|
||||
];
|
||||
const data = await gdrive.files.list({
|
||||
q: query.join(" and "),
|
||||
@@ -522,21 +515,16 @@ export async function SearchFile(
|
||||
}),
|
||||
});
|
||||
const encryptedData: z.infer<typeof Schema_File>[] = [];
|
||||
if (!data.data.files?.length)
|
||||
return { files: [], nextPageToken: undefined };
|
||||
if (!data.data.files?.length) return { files: [], nextPageToken: undefined };
|
||||
for (const file of data.data.files) {
|
||||
encryptedData.push({
|
||||
mimeType: file.mimeType as string,
|
||||
encryptedId: await encryptData(file.id as string),
|
||||
name: file.name as string,
|
||||
trashed: (file.trashed as boolean) ?? false,
|
||||
modifiedTime: new Date(
|
||||
file.modifiedTime as string,
|
||||
).toLocaleDateString(),
|
||||
modifiedTime: new Date(file.modifiedTime as string).toLocaleDateString(),
|
||||
fileExtension: file.fileExtension || undefined,
|
||||
encryptedWebContentLink: file.webContentLink
|
||||
? await encryptData(file.webContentLink)
|
||||
: undefined,
|
||||
encryptedWebContentLink: file.webContentLink ? await encryptData(file.webContentLink) : undefined,
|
||||
size: file.size ? Number(file.size) : undefined,
|
||||
thumbnailLink: file.thumbnailLink || undefined,
|
||||
imageMediaMetadata: file.imageMediaMetadata
|
||||
@@ -611,8 +599,7 @@ export async function GetContent(encryptedId: string): Promise<string> {
|
||||
},
|
||||
);
|
||||
|
||||
if (typeof file !== "string")
|
||||
throw new Error("It seems the file is not a text file");
|
||||
if (typeof file !== "string") throw new Error("It seems the file is not a text file");
|
||||
|
||||
return file as string;
|
||||
} catch (error) {
|
||||
@@ -621,9 +608,7 @@ export async function GetContent(encryptedId: string): Promise<string> {
|
||||
throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
export async function GetReadme(
|
||||
encryptedId: string | undefined,
|
||||
): Promise<string | null> {
|
||||
export async function GetReadme(encryptedId: string | undefined): Promise<string | null> {
|
||||
try {
|
||||
let decryptedId;
|
||||
if (encryptedId) decryptedId = await decryptData(encryptedId);
|
||||
@@ -653,6 +638,8 @@ export async function GetReadme(
|
||||
corpora: "drive",
|
||||
}),
|
||||
});
|
||||
|
||||
console.log(data.files?.length);
|
||||
if (!data.files?.length) return null;
|
||||
|
||||
let file;
|
||||
@@ -663,16 +650,15 @@ export async function GetReadme(
|
||||
// Check by mimetype, use google-apps.shortcut last
|
||||
file = data.files.find((item) => item.mimeType === "text/markdown");
|
||||
if (!file) {
|
||||
file = data.files.find(
|
||||
(item) => item.mimeType === "application/vnd.google-apps.shortcut",
|
||||
);
|
||||
file = data.files.find((item) => item.mimeType === "application/vnd.google-apps.shortcut");
|
||||
}
|
||||
}
|
||||
|
||||
if (!file) return null;
|
||||
if (
|
||||
file.mimeType !== "text/markdown" &&
|
||||
file.mimeType !== "application/vnd.google-apps.shortcut"
|
||||
file.mimeType !== "application/vnd.google-apps.shortcut" &&
|
||||
file.mimeType !== "text/plain"
|
||||
)
|
||||
return null;
|
||||
|
||||
@@ -685,8 +671,7 @@ export async function GetReadme(
|
||||
data: { shortcutDetails: { targetId: string; targetMimeType: string } };
|
||||
};
|
||||
if (!shortcutData.shortcutDetails.targetId) return null;
|
||||
if (shortcutData.shortcutDetails.targetMimeType !== "text/markdown")
|
||||
return null;
|
||||
if (shortcutData.shortcutDetails.targetMimeType !== "text/markdown") return null;
|
||||
|
||||
const { data: content } = await gdrive.files.get(
|
||||
{
|
||||
@@ -720,9 +705,7 @@ export async function GetReadme(
|
||||
throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
export async function GetBanner(
|
||||
encryptedId: string | undefined,
|
||||
): Promise<string | null> {
|
||||
export async function GetBanner(encryptedId: string | undefined): Promise<string | null> {
|
||||
try {
|
||||
let decryptedId;
|
||||
if (encryptedId) decryptedId = await decryptData(encryptedId);
|
||||
@@ -770,14 +753,10 @@ export async function GetWebContent(encrypted: string): Promise<string> {
|
||||
throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
export async function CreateDownloadToken(
|
||||
duration: number = config.apiConfig.temporaryTokenDuration,
|
||||
): Promise<string> {
|
||||
export async function CreateDownloadToken(duration: number = config.apiConfig.temporaryTokenDuration): Promise<string> {
|
||||
try {
|
||||
const data = {
|
||||
expiredAt:
|
||||
Date.now() +
|
||||
duration * 60 * 60 * 1000 * config.apiConfig.temporaryTokenDuration,
|
||||
expiredAt: Date.now() + duration * 60 * 60 * 1000 * config.apiConfig.temporaryTokenDuration,
|
||||
};
|
||||
const token = await encryptData(JSON.stringify(data));
|
||||
return token;
|
||||
@@ -796,8 +775,7 @@ export async function CheckDownloadToken(token: string): Promise<{
|
||||
if (decryptToken.expiredAt < Date.now()) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
"Download token expired, please click the download button again to get a new token",
|
||||
message: "Download token expired, please click the download button again to get a new token",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -824,10 +802,7 @@ export async function GenerateAESKey(): Promise<string> {
|
||||
throw new Error(e.message);
|
||||
}
|
||||
}
|
||||
export async function VerifyAESKey(
|
||||
data: string,
|
||||
key: string,
|
||||
): Promise<boolean> {
|
||||
export async function VerifyAESKey(data: string, key: string): Promise<boolean> {
|
||||
try {
|
||||
let paddedKey;
|
||||
if (key.length < 16) {
|
||||
|
||||
Reference in New Issue
Block a user