diff --git a/src/actions/files.ts b/src/actions/files.ts index 49d75c0..d070e7c 100644 --- a/src/actions/files.ts +++ b/src/actions/files.ts @@ -342,10 +342,33 @@ export async function GetBanner(id: string | null = null): Promise> { +/** + * Get content of text file + * @param id - File ID to fetch + */ +export async function GetContent(id: string): Promise> { + const decryptedId = await encryptionService.decrypt(id); + + const { data, status, statusText } = await gdrive.files.get( + { + fileId: decryptedId, + alt: "media", + supportsAllDrives: config.apiConfig.isTeamDrive, + }, + { + responseType: "text", + }, + ); + if (status !== 200) + return { + success: false, + message: "Failed to fetch content", + error: statusText, + }; + return { success: true, - message: "Token created", - data: "", + message: "Content found", + data: data as string, }; } diff --git a/src/actions/paths.ts b/src/actions/paths.ts index 637bf4d..70fc7f9 100644 --- a/src/actions/paths.ts +++ b/src/actions/paths.ts @@ -36,6 +36,7 @@ export async function GetFilePaths(fileName: string, parentId?: string): Promise const { data } = await gdrive.files.get({ fileId: parentIdTemp, fields: "id,name,parents", + supportsAllDrives: config.apiConfig.isTeamDrive, }); if (!data.name) break; diff --git a/src/actions/token.ts b/src/actions/token.ts new file mode 100644 index 0000000..0af65d2 --- /dev/null +++ b/src/actions/token.ts @@ -0,0 +1,71 @@ +"use server"; + +import { type z } from "zod"; +import { type ActionResponseSchema } from "~/types"; + +import { encryptionService } from "~/lib/utils.server"; + +import { type Schema_File, Schema_FileToken } from "~/types/schema"; + +import config from "config"; + +/** + * Create a token to download a file + * @param file - File data + * @param expiredIn - Token expiration time in milliseconds (default to configuration) + */ +export async function CreateFileToken( + file: z.infer, + expiredIn: number = 3600 * 1000 * config.apiConfig.temporaryTokenDuration, +): Promise> { + const tokenObject = { + id: file.encryptedId, + exp: Date.now() + expiredIn, + iat: Date.now(), + }; + const parsedTokenObject = Schema_FileToken.safeParse(tokenObject); + if (!parsedTokenObject.success) + return { + success: false, + message: "Failed to create token", + error: parsedTokenObject.error.message, + }; + + const token = await encryptionService.encrypt(JSON.stringify(parsedTokenObject.data)); + + return { + success: true, + message: "Token created", + data: token, + }; +} + +/** + * Validate a file token and return the token data + * @param token - The token to validate + */ +export async function ValidateFileToken( + token: string, +): Promise>> { + const decryptedToken = await encryptionService.decrypt(token); + const parsedToken = Schema_FileToken.safeParse(JSON.parse(decryptedToken)); + if (!parsedToken.success) + return { + success: false, + message: "Failed to validate token", + error: parsedToken.error.message, + }; + const currentTime = Date.now(); + if (parsedToken.data.exp < currentTime) + return { + success: false, + message: "Token expired", + error: "Download URL expired", + }; + + return { + success: true, + message: "Token validated", + data: parsedToken.data, + }; +}