@muhgholy/next-drive 4.23.10 → 4.23.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-XUPDNN2U.js → chunk-26KZWPCF.js} +25 -9
- package/dist/chunk-26KZWPCF.js.map +1 -0
- package/dist/{chunk-V75PCJHT.cjs → chunk-NDHVF2IB.cjs} +25 -9
- package/dist/chunk-NDHVF2IB.cjs.map +1 -0
- package/dist/server/actions/drive.d.ts +1 -0
- package/dist/server/actions/drive.d.ts.map +1 -1
- package/dist/server/express.cjs +11 -11
- package/dist/server/express.js +2 -2
- package/dist/server/hono.cjs +11 -11
- package/dist/server/hono.js +2 -2
- package/dist/server/index.cjs +18 -18
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-V75PCJHT.cjs.map +0 -1
- package/dist/chunk-XUPDNN2U.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/database/mongoose/schema/drive.ts","../src/server/utils/migration.ts","../src/server/config.ts","../src/server/actions/cors.ts","../src/server/utils.ts","../src/server/security/crypto-utils.ts","../src/server/storage-adapters/local.ts","../src/server/database/mongoose/schema/storage/account.ts","../src/server/storage-adapters/google.ts","../src/server/actions/public.ts","../src/server/actions/auth.ts","../src/server/zod/schemas.ts","../src/server/controllers/drive.ts","../src/server/actions/shared.ts","../src/server/actions/drive.ts","../src/server/index.ts"],"names":["Schema","mongoose","fs","path","os","crypto","sharp","ffmpeg","getNextOrderValue","owner","folderIds","google","stream","z","isValidObjectId","formidable","uploadDir"],"mappings":"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","file":"chunk-V75PCJHT.cjs","sourcesContent":["// ** Mongoose Drive Schema\nimport type {\n TDatabaseDrive,\n TDatabaseDriveInformation,\n TDatabaseDriveMetadata,\n TDatabaseDriveProvider,\n TDatabaseDriveStatus,\n} from '@/types/lib/database/drive';\nimport mongoose, { Schema, type Document, type Model, type Types } from 'mongoose';\n\nexport interface IDatabaseDriveDocument extends Document {\n owner: Record<string, unknown> | null;\n storageAccountId: Types.ObjectId | null;\n name: string;\n parentId: Types.ObjectId | null;\n order: number;\n provider: TDatabaseDriveProvider;\n metadata: TDatabaseDriveMetadata;\n information: TDatabaseDriveInformation;\n status: TDatabaseDriveStatus;\n trashedAt: Date | null;\n expiresAt: Date | null;\n meta: Record<string, unknown>;\n createdAt: Date;\n\n toClient: () => Promise<TDatabaseDrive>;\n}\n\n// ** Schema definition\nconst informationSchema = new Schema({\n type: { type: String, enum: ['FILE', 'FOLDER'], required: true },\n sizeInBytes: { type: Number, default: 0 },\n mime: { type: String },\n path: { type: String },\n width: { type: Number },\n height: { type: Number },\n duration: { type: Number },\n hash: { type: String },\n}, { _id: false });\n\n// Provider Sub-schema to handle 'type' field correctly without ambiguity\nconst providerSchema = new Schema({\n type: { type: String, enum: ['LOCAL', 'GOOGLE'], required: true, default: 'LOCAL' },\n google: { type: Schema.Types.Mixed }\n}, { _id: false });\n\nconst DriveSchema: Schema = new Schema<IDatabaseDriveDocument>(\n {\n owner: { type: Schema.Types.Mixed, default: null },\n storageAccountId: { type: Schema.Types.ObjectId, ref: 'StorageAccount', default: null },\n name: { type: String, required: true },\n parentId: { type: Schema.Types.ObjectId, ref: 'Drive', default: null },\n order: { type: Number, default: 0 },\n provider: { type: providerSchema, default: () => ({ type: 'LOCAL' }) },\n metadata: { type: Schema.Types.Mixed, default: {} },\n information: { type: informationSchema, required: true },\n status: { type: String, enum: ['READY', 'PROCESSING', 'UPLOADING', 'FAILED'], default: 'PROCESSING' },\n trashedAt: { type: Date, default: null },\n expiresAt: { type: Date, default: null },\n meta: { type: Schema.Types.Mixed, default: {} },\n createdAt: { type: Date, default: Date.now },\n },\n { minimize: false },\n);\n\n// ** Indexes\nDriveSchema.index({ owner: 1, 'information.type': 1 });\nDriveSchema.index({ owner: 1, 'provider.type': 1, 'provider.google.id': 1 }); // Provider lookup updated\nDriveSchema.index({ owner: 1, storageAccountId: 1 });\nDriveSchema.index({ owner: 1, trashedAt: 1 });\nDriveSchema.index({ owner: 1, 'information.hash': 1 });\nDriveSchema.index({ owner: 1, name: 'text' });\nDriveSchema.index({ owner: 1, 'provider.type': 1 });\nDriveSchema.index({ expiresAt: 1 });\n\n// ** Method: toClient\nDriveSchema.method<IDatabaseDriveDocument>('toClient', async function (): Promise<TDatabaseDrive> {\n const data = this.toJSON<IDatabaseDriveDocument>();\n\n return {\n id: String(data._id),\n name: data.name,\n parentId: data.parentId ? String(data.parentId) : null,\n order: data.order,\n provider: data.provider,\n metadata: data.metadata,\n information: data.information,\n status: data.status,\n trashedAt: data.trashedAt,\n expiresAt: data.expiresAt,\n meta: data.meta,\n createdAt: data.createdAt,\n };\n});\n\nconst Drive: Model<IDatabaseDriveDocument> = mongoose.models.Drive || mongoose.model<IDatabaseDriveDocument>('Drive', DriveSchema);\n\nexport default Drive;\n\n","// ** Storage Migration Utility\n// ** Handles one-time migrations for storage structure changes\nimport fs from 'fs';\nimport path from 'path';\nimport mongoose from 'mongoose';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport type { TMigration } from '@/types/server/migration';\n\n// ** Migration version tracking\nconst MIGRATION_FILE = '.migration-version';\nconst CURRENT_VERSION = 1;\n\n// ** Check if system is ready for migration\nconst isReadyForMigration = (): boolean => {\n // ** Database must be connected\n if (mongoose.connection.readyState !== 1) {\n console.warn('[next-drive] Migration skipped: Database not connected');\n return false;\n }\n return true;\n};\n\n// ** Check if this is a new installation (no existing files to migrate)\nconst isNewInstallation = (storagePath: string): boolean => {\n // ** If storage path doesn't exist, it's a new installation\n if (!fs.existsSync(storagePath)) return true;\n\n // ** Check if there are any old-style directories to migrate\n const hasOldDriveDir = fs.existsSync(path.join(storagePath, 'drive'));\n const hasOldCacheDir = fs.existsSync(path.join(storagePath, 'cache', 'thumbnails'));\n const hasOldLibraryDir = fs.existsSync(path.join(storagePath, 'library', 'google'));\n\n // ** Check for files directly in storage root (old format: {id}/data.ext)\n const hasRootLevelFiles = fs.existsSync(storagePath) &&\n fs.readdirSync(storagePath).some(entry => {\n const entryPath = path.join(storagePath, entry);\n // ** Look for directories that look like MongoDB ObjectIds (24 hex chars)\n return fs.statSync(entryPath).isDirectory() &&\n /^[a-f0-9]{24}$/i.test(entry) &&\n entry !== 'file'; // Exclude new 'file' directory\n });\n\n // ** If none of these exist, it's effectively a new installation\n return !hasOldDriveDir && !hasOldCacheDir && !hasOldLibraryDir && !hasRootLevelFiles;\n};\n\n// ** Migration definitions (add new migrations here)\nconst migrations: TMigration[] = [\n {\n version: 1,\n name: 'restructure-file-paths',\n migrate: async (storagePath: string) => {\n // ** Migrate from old structure to new structure\n // ** Old: {storagePath}/{fileId}/data.{ext} or {storagePath}/drive/{fileId}/data.bin\n // ** New: {storagePath}/file/{fileId}/data.bin\n\n const fileDir = path.join(storagePath, 'file');\n if (!fs.existsSync(fileDir)) {\n fs.mkdirSync(fileDir, { recursive: true });\n }\n\n // ** Find all LOCAL files in database\n const files = await Drive.find({\n 'provider.type': 'LOCAL',\n 'information.type': 'FILE',\n 'information.path': { $exists: true, $ne: '' },\n }).lean();\n\n for (const file of files) {\n const info = file.information as { type: string; path?: string };\n const oldPath = info.path;\n if (!oldPath) continue;\n\n // ** Skip if already migrated (starts with 'file/')\n if (oldPath.startsWith('file/')) continue;\n\n const fileId = String(file._id);\n const newRelativePath = path.join('file', fileId, 'data.bin');\n const oldFullPath = path.join(storagePath, oldPath);\n const newFullPath = path.join(storagePath, newRelativePath);\n\n // ** Check if old file exists\n if (fs.existsSync(oldFullPath)) {\n const newDir = path.dirname(newFullPath);\n if (!fs.existsSync(newDir)) {\n fs.mkdirSync(newDir, { recursive: true });\n }\n\n // ** Move file to new location\n try {\n fs.renameSync(oldFullPath, newFullPath);\n } catch (err: unknown) {\n if (err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'EXDEV') {\n fs.copyFileSync(oldFullPath, newFullPath);\n fs.unlinkSync(oldFullPath);\n } else {\n console.error(`[next-drive] Migration failed for file ${fileId}:`, err);\n continue;\n }\n }\n\n // ** Cleanup old directory if empty\n const oldDir = path.dirname(oldFullPath);\n try {\n const remaining = fs.readdirSync(oldDir);\n if (remaining.length === 0) {\n fs.rmdirSync(oldDir);\n }\n } catch { /* ignore cleanup errors */ }\n }\n\n // ** Update database path\n await Drive.updateOne(\n { _id: file._id },\n { $set: { 'information.path': newRelativePath } }\n );\n }\n\n // ** Migrate old cache directory\n const oldCacheDir = path.join(storagePath, 'cache', 'thumbnails');\n if (fs.existsSync(oldCacheDir)) {\n const thumbnails = fs.readdirSync(oldCacheDir);\n for (const thumb of thumbnails) {\n const fileId = thumb.replace('.webp', '');\n const oldThumbPath = path.join(oldCacheDir, thumb);\n const newThumbDir = path.join(storagePath, 'file', fileId, 'cache');\n const newThumbPath = path.join(newThumbDir, 'thumbnail.webp');\n\n if (fs.existsSync(oldThumbPath) && !fs.existsSync(newThumbPath)) {\n if (!fs.existsSync(newThumbDir)) {\n fs.mkdirSync(newThumbDir, { recursive: true });\n }\n try {\n fs.renameSync(oldThumbPath, newThumbPath);\n } catch {\n // Ignore errors, thumbnail can be regenerated\n }\n }\n }\n\n // ** Cleanup old cache directory\n try {\n fs.rmSync(oldCacheDir, { recursive: true, force: true });\n const cacheParent = path.join(storagePath, 'cache');\n const remaining = fs.readdirSync(cacheParent);\n if (remaining.length === 0) {\n fs.rmdirSync(cacheParent);\n }\n } catch { /* ignore cleanup errors */ }\n }\n\n // ** Migrate old library/google directory\n const oldLibraryDir = path.join(storagePath, 'library', 'google');\n if (fs.existsSync(oldLibraryDir)) {\n const cachedFiles = fs.readdirSync(oldLibraryDir);\n for (const cached of cachedFiles) {\n // Extract fileId from filename (format: {fileId}.{ext})\n const fileId = cached.split('.')[0];\n if (!fileId) continue;\n\n const oldCachedPath = path.join(oldLibraryDir, cached);\n const newCachedDir = path.join(storagePath, 'file', fileId);\n const newCachedPath = path.join(newCachedDir, 'data.bin');\n\n if (fs.existsSync(oldCachedPath) && !fs.existsSync(newCachedPath)) {\n if (!fs.existsSync(newCachedDir)) {\n fs.mkdirSync(newCachedDir, { recursive: true });\n }\n try {\n fs.renameSync(oldCachedPath, newCachedPath);\n } catch {\n // Ignore errors, can be re-downloaded\n }\n }\n }\n\n // ** Cleanup old library directory\n try {\n fs.rmSync(path.join(storagePath, 'library'), { recursive: true, force: true });\n } catch { /* ignore cleanup errors */ }\n }\n\n // ** Cleanup old 'drive' directory if exists\n const oldDriveDir = path.join(storagePath, 'drive');\n if (fs.existsSync(oldDriveDir)) {\n try {\n fs.rmSync(oldDriveDir, { recursive: true, force: true });\n } catch { /* ignore cleanup errors */ }\n }\n\n console.log('[next-drive] Migration v1 complete: restructure-file-paths');\n },\n },\n];\n\n// ** Run pending migrations\nexport const runMigrations = async (storagePath: string): Promise<void> => {\n // ** Check readiness before attempting migration\n if (!isReadyForMigration()) {\n return;\n }\n\n // ** Ensure storage path exists\n if (!fs.existsSync(storagePath)) {\n fs.mkdirSync(storagePath, { recursive: true });\n }\n\n const versionFile = path.join(storagePath, MIGRATION_FILE);\n let currentVersion = 0;\n\n // ** Read current version\n if (fs.existsSync(versionFile)) {\n try {\n currentVersion = parseInt(fs.readFileSync(versionFile, 'utf-8').trim(), 10) || 0;\n } catch {\n currentVersion = 0;\n }\n }\n\n // ** Skip if already at current version\n if (currentVersion >= CURRENT_VERSION) return;\n\n // ** For new installations, just write the version file and skip migration\n if (isNewInstallation(storagePath)) {\n console.log('[next-drive] New installation detected, skipping migration');\n fs.writeFileSync(versionFile, String(CURRENT_VERSION));\n return;\n }\n\n // ** Run pending migrations\n const pendingMigrations = migrations.filter(m => m.version > currentVersion);\n for (const migration of pendingMigrations.sort((a, b) => a.version - b.version)) {\n console.log(`[next-drive] Running migration v${migration.version}: ${migration.name}`);\n try {\n await migration.migrate(storagePath);\n // ** Update version after each successful migration\n fs.writeFileSync(versionFile, String(migration.version));\n } catch (error) {\n console.error(`[next-drive] Migration v${migration.version} failed:`, error);\n throw error;\n }\n }\n}\n","// ** Server Config Wrapper\nimport mongoose from 'mongoose';\nimport path from 'path';\nimport os from 'os';\nimport type { TDriveConfiguration, TDriveConfigInformation, TDriveInformationInput } from '@/types/server';\nimport { runMigrations } from '@/server/utils/migration';\n\n// ** Use globalThis to persist config across all module instances\n// Next.js (especially with Turbopack) creates separate SSR chunks for\n// Pages Router, App Router, and Server Actions — module-level variables\n// are NOT shared between them. globalThis is process-wide.\ntype TNextDriveGlobal = {\n config: TDriveConfiguration | null;\n migrationPromise: Promise<void> | null;\n initialized: boolean;\n abuse: { ipHits: Map<string, number[]>; concurrent: number };\n};\n\nconst GLOBAL_KEY = '__nextDrive' as const;\n\nconst getGlobal = (): TNextDriveGlobal => {\n if (!(globalThis as any)[GLOBAL_KEY]) {\n (globalThis as any)[GLOBAL_KEY] = {\n config: null,\n migrationPromise: null,\n initialized: false,\n abuse: { ipHits: new Map(), concurrent: 0 },\n };\n }\n return (globalThis as any)[GLOBAL_KEY];\n};\n\n// ** Initialize configuration\nexport const driveConfiguration = async (config: TDriveConfiguration): Promise<TDriveConfiguration> => {\n const g = getGlobal();\n\n // ** Check database connection\n if (mongoose.connection.readyState !== 1) {\n throw new Error('Database not connected. Please connect to Mongoose before initializing next-drive.');\n }\n\n // ** If already initialized, just wait for migration and return\n if (g.initialized && g.config) {\n if (g.migrationPromise) await g.migrationPromise;\n return g.config;\n }\n\n\n // Resolve storage path with fallback to temp dir\n const resolvedPath = config.storage?.path || path.join(os.tmpdir(), 'next-drive-data');\n\n const mode = config.mode || 'NORMAL';\n\n // ** Set config FIRST (before migrations) so it's available during migration\n if (mode === 'ROOT') {\n g.config = {\n ...config,\n mode: 'ROOT',\n storage: {\n ...config.storage,\n path: resolvedPath,\n },\n security: {\n maxUploadSizeInBytes: config.security?.maxUploadSizeInBytes ?? 1024 * 1024 * 1024 * 10, // 10GB default for ROOT\n allowedMimeTypes: config.security?.allowedMimeTypes ?? ['*/*'],\n signedUrls: config.security?.signedUrls,\n trash: config.security?.trash,\n unauthenticated: config.security?.unauthenticated,\n },\n };\n } else {\n if (!config.information) {\n throw new Error('information callback is required in NORMAL mode');\n }\n\n g.config = {\n ...config,\n mode: 'NORMAL',\n storage: {\n ...config.storage,\n path: resolvedPath,\n },\n security: {\n maxUploadSizeInBytes: config.security?.maxUploadSizeInBytes ?? 10 * 1024 * 1024,\n allowedMimeTypes: config.security?.allowedMimeTypes ?? ['*/*'],\n signedUrls: config.security?.signedUrls,\n trash: config.security?.trash,\n unauthenticated: config.security?.unauthenticated,\n },\n information: config.information,\n };\n }\n\n // ** Mark as initialized immediately to prevent race conditions\n g.initialized = true;\n\n // ** Run migrations once (all concurrent callers share the same promise)\n if (!g.migrationPromise) {\n g.migrationPromise = runMigrations(resolvedPath);\n }\n await g.migrationPromise;\n\n return g.config;\n};\n\n// ** Get current configuration\nexport const getDriveConfig = (): TDriveConfiguration => {\n const g = getGlobal();\n if (!g.config) throw new Error('Drive configuration not initialized');\n return g.config;\n};\n\n// ** Get drive information (quota, owner) - Accepts REQUEST (from API handler) or KEY (from server-side code)\nexport const getDriveInformation = async (input: TDriveInformationInput): Promise<TDriveConfigInformation> => {\n const config = getDriveConfig();\n\n // In ROOT mode, return null key if information callback is not provided\n if (config.mode === 'ROOT') {\n if (!config.information) {\n return {\n key: input.method === 'KEY' ? input.key : null,\n storage: { quotaInBytes: Number.MAX_SAFE_INTEGER } // Unlimited quota in ROOT mode\n };\n }\n return config.information(input);\n }\n\n // NORMAL mode - information is guaranteed to exist\n return config.information(input);\n};\n\n","import type { NextApiRequest, NextApiResponse } from 'next';\nimport { getDriveConfig } from '@/server/config';\n\nexport const applyCorsHeaders = (req: NextApiRequest, res: NextApiResponse, config: ReturnType<typeof getDriveConfig>): boolean => {\n const cors = config.cors;\n if (!cors?.enabled) return false;\n\n const origin = req.headers.origin;\n const allowedOrigins = cors.origins ?? '*';\n const methods = cors.methods ?? ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'];\n const allowedHeaders = cors.allowedHeaders ?? ['Content-Type', 'Authorization', 'X-Drive-Account'];\n const exposedHeaders = cors.exposedHeaders ?? ['Content-Length', 'Content-Type', 'Content-Disposition'];\n const credentials = cors.credentials ?? false;\n const maxAge = cors.maxAge ?? 86400;\n\n let allowOrigin: string | null = null;\n if (origin) {\n if (allowedOrigins === '*') {\n allowOrigin = origin;\n } else if (Array.isArray(allowedOrigins)) {\n if (allowedOrigins.includes(origin)) {\n allowOrigin = origin;\n }\n } else if (allowedOrigins === origin) {\n allowOrigin = origin;\n }\n } else if (allowedOrigins === '*') {\n allowOrigin = '*';\n }\n\n if (!allowOrigin) {\n if (req.method === 'OPTIONS') {\n res.status(403).end();\n return true;\n }\n return false;\n }\n\n res.setHeader('Access-Control-Allow-Origin', allowOrigin);\n res.setHeader('Access-Control-Allow-Methods', methods.join(', '));\n res.setHeader('Access-Control-Allow-Headers', allowedHeaders.join(', '));\n res.setHeader('Access-Control-Expose-Headers', exposedHeaders.join(', '));\n res.setHeader('Access-Control-Max-Age', maxAge.toString());\n\n if (credentials) {\n res.setHeader('Access-Control-Allow-Credentials', 'true');\n }\n\n if (req.method === 'OPTIONS') {\n res.status(204).end();\n return true;\n }\n\n return false;\n};\n","import fs from 'fs';\nimport crypto from 'crypto';\nimport sharp from 'sharp';\n\nexport const isImageMimeType = (mime: string): boolean => ['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'image/avif'].includes(mime);\n\nexport const validateMimeType = (mime: string, allowedTypes: string[]): boolean => {\n if (allowedTypes.includes('*/*')) return true;\n return allowedTypes.some(pattern => {\n if (pattern === mime) return true;\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2);\n return mime.startsWith(`${prefix}/`);\n }\n return false;\n });\n};\n\nexport const computeFileHash = (filePath: string): Promise<string> =>\n new Promise((resolve, reject) => {\n const hash = crypto.createHash('sha256');\n const stream = fs.createReadStream(filePath);\n stream.on('data', data => hash.update(data));\n stream.on('end', () => resolve(hash.digest('hex')));\n stream.on('error', reject);\n });\n\nexport const extractImageMetadata = async (filePath: string) => {\n try {\n const { width = 0, height = 0, exif } = await sharp(filePath).metadata();\n return { width, height, ...(exif && { exif: { raw: exif.toString('base64') } }) };\n } catch {\n return null;\n }\n};\n\nexport const formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nexport const ownerMatches = (a: Record<string, unknown> | null, b: Record<string, unknown> | null): boolean => {\n if (a === null && b === null) return true;\n if (a === null || b === null) return false;\n return JSON.stringify(a) === JSON.stringify(b);\n};\n\n/**\n * Fit options for resizing (maps to Sharp's fit option)\n */\nexport type FitOption = 'cover' | 'contain' | 'fill' | 'inside' | 'outside';\n\n/**\n * Position/gravity options for crop (maps to Sharp's position option)\n */\nexport type PositionOption = 'center' | 'top' | 'right top' | 'right' | 'right bottom' | 'bottom' | 'left bottom' | 'left' | 'left top' | 'attention' | 'entropy';\n\n/**\n * Image optimization settings returned by getImageSettings\n */\nexport interface ImageSettings {\n quality: number; // 1-100, lower = more compression\n effort: number; // 0-9 for webp/avif, higher = slower but smaller\n pngCompression: number; // 0-9 for PNG, higher = more compression\n width?: number; // Target width (resize)\n height?: number; // Target height (resize)\n fit?: FitOption; // How to fit image into dimensions\n position?: PositionOption; // Crop position when using cover fit\n}\n\n/**\n * Display presets - defines aspect ratio, base dimensions, quality factor, and default fit\n */\nconst DISPLAY_PRESETS: Record<string, {\n ratio: [number, number];\n baseWidth: number;\n qualityFactor: number;\n defaultFit: FitOption;\n}> = {\n 'article-header': { ratio: [16, 9], baseWidth: 1200, qualityFactor: 0.9, defaultFit: 'inside' },\n 'article-image': { ratio: [16, 9], baseWidth: 800, qualityFactor: 0.85, defaultFit: 'inside' },\n 'thumbnail': { ratio: [1, 1], baseWidth: 150, qualityFactor: 0.7, defaultFit: 'cover' },\n 'avatar': { ratio: [1, 1], baseWidth: 128, qualityFactor: 0.8, defaultFit: 'cover' },\n 'logo': { ratio: [2, 1], baseWidth: 200, qualityFactor: 0.95, defaultFit: 'inside' },\n 'card': { ratio: [4, 3], baseWidth: 400, qualityFactor: 0.8, defaultFit: 'cover' },\n 'gallery': { ratio: [1, 1], baseWidth: 600, qualityFactor: 0.85, defaultFit: 'cover' },\n 'og': { ratio: [1200, 630], baseWidth: 1200, qualityFactor: 0.9, defaultFit: 'cover' },\n 'icon': { ratio: [1, 1], baseWidth: 48, qualityFactor: 0.75, defaultFit: 'cover' },\n 'cover': { ratio: [16, 9], baseWidth: 1920, qualityFactor: 0.9, defaultFit: 'cover' },\n 'story': { ratio: [9, 16], baseWidth: 1080, qualityFactor: 0.85, defaultFit: 'cover' },\n 'video': { ratio: [16, 9], baseWidth: 1280, qualityFactor: 0.85, defaultFit: 'cover' },\n 'banner': { ratio: [3, 1], baseWidth: 1200, qualityFactor: 0.9, defaultFit: 'cover' },\n 'portrait': { ratio: [3, 4], baseWidth: 600, qualityFactor: 0.85, defaultFit: 'inside' },\n 'landscape': { ratio: [4, 3], baseWidth: 800, qualityFactor: 0.85, defaultFit: 'inside' },\n};\n\n/**\n * Valid fit options\n */\nconst VALID_FIT_OPTIONS: FitOption[] = ['cover', 'contain', 'fill', 'inside', 'outside'];\n\n/**\n * Valid position options (for cover/contain)\n */\nconst VALID_POSITION_OPTIONS: PositionOption[] = [\n 'center', 'top', 'right top', 'right', 'right bottom',\n 'bottom', 'left bottom', 'left', 'left top', 'attention', 'entropy'\n];\n\n/**\n * Size scale factors - multiplies the display's baseWidth\n */\nconst SIZE_SCALES: Record<string, number> = {\n 'xs': 0.25,\n 'sm': 0.5,\n 'md': 1.0,\n 'lg': 1.5,\n 'xl': 2.0,\n '2xl': 2.5,\n};\n\n/**\n * Standalone size presets - used when no display is specified\n */\nconst STANDALONE_SIZES: Record<string, { width: number; height: number }> = {\n 'xs': { width: 64, height: 64 },\n 'sm': { width: 128, height: 128 },\n 'md': { width: 256, height: 256 },\n 'lg': { width: 512, height: 512 },\n 'xl': { width: 1024, height: 1024 },\n '2xl': { width: 1600, height: 1600 },\n 'icon': { width: 48, height: 48 },\n 'thumb': { width: 150, height: 150 },\n 'square': { width: 600, height: 600 },\n 'avatar-sm': { width: 64, height: 64 },\n 'avatar-md': { width: 128, height: 128 },\n 'avatar-lg': { width: 256, height: 256 },\n 'landscape-sm': { width: 480, height: 270 },\n 'landscape': { width: 800, height: 450 },\n 'landscape-lg': { width: 1280, height: 720 },\n 'landscape-xl': { width: 1920, height: 1080 },\n 'portrait-sm': { width: 270, height: 480 },\n 'portrait': { width: 450, height: 800 },\n 'portrait-lg': { width: 720, height: 1280 },\n 'wide': { width: 1200, height: 630 },\n 'banner': { width: 1200, height: 400 },\n 'banner-sm': { width: 800, height: 200 },\n 'photo-4x3': { width: 800, height: 600 },\n 'photo-3x2': { width: 900, height: 600 },\n 'story': { width: 1080, height: 1920 },\n 'video': { width: 1280, height: 720 },\n 'video-sm': { width: 640, height: 360 },\n 'card-sm': { width: 300, height: 200 },\n 'card': { width: 400, height: 300 },\n 'card-lg': { width: 600, height: 400 },\n};\n\n/**\n * Calculates all image optimization settings based on file size, quality, display, size, fit, and position.\n * \n * @param fileSizeInBytes - Original file size in bytes\n * @param qualityPreset - Quality preset ('low', 'medium', 'high') or number (1-100)\n * @param display - Display context preset (sets aspect ratio + quality factor + default fit)\n * @param size - Size scale (xs/sm/md/lg/xl) or standalone dimension preset\n * @param fit - Fit mode (cover/contain/fill/inside/outside). Uses display default if not specified.\n * @param position - Position for cover/contain (center/top/bottom/left/right/attention/entropy)\n * @returns Complete image settings including quality, effort, dimensions, fit, and position\n */\nexport const getImageSettings = (\n fileSizeInBytes: number | undefined,\n qualityPreset: string | undefined,\n display: string | undefined,\n size: string | undefined,\n fit?: string,\n position?: string\n): ImageSettings => {\n // 1. Parse base quality from preset\n let baseQuality = 80;\n if (qualityPreset === 'low') baseQuality = 30;\n else if (qualityPreset === 'medium') baseQuality = 50;\n else if (qualityPreset === 'high') baseQuality = 75;\n else if (qualityPreset) {\n const n = parseInt(qualityPreset, 10);\n if (!isNaN(n)) baseQuality = Math.min(100, Math.max(1, n));\n }\n\n // 2. Calculate dimensions, quality factor, and default fit\n let width: number | undefined;\n let height: number | undefined;\n let qualityFactor = 1.0;\n let defaultFit: FitOption = 'inside';\n\n const displayPreset = display ? DISPLAY_PRESETS[display] : undefined;\n\n if (displayPreset) {\n // Display is specified - use its aspect ratio and default fit\n qualityFactor = displayPreset.qualityFactor;\n defaultFit = displayPreset.defaultFit;\n const [ratioW, ratioH] = displayPreset.ratio;\n\n // Apply size scale if it's a scale factor (xs/sm/md/lg/xl)\n const scale = size && SIZE_SCALES[size] ? SIZE_SCALES[size] : 1.0;\n width = Math.round(displayPreset.baseWidth * scale);\n height = Math.round(width * ratioH / ratioW);\n } else if (size) {\n // No display, check standalone sizes\n const standalone = STANDALONE_SIZES[size];\n if (standalone) {\n width = standalone.width;\n height = standalone.height;\n }\n }\n\n // 3. Resolve fit and position\n const resolvedFit: FitOption = fit && VALID_FIT_OPTIONS.includes(fit as FitOption)\n ? (fit as FitOption)\n : defaultFit;\n\n const resolvedPosition: PositionOption | undefined = position && VALID_POSITION_OPTIONS.includes(position as PositionOption)\n ? (position as PositionOption)\n : undefined;\n\n // Apply quality factor from display\n baseQuality = Math.round(baseQuality * qualityFactor);\n\n // 4. Apply file size dynamic adjustment\n let quality = baseQuality;\n let effort = 4;\n let pngCompression = 6;\n\n if (fileSizeInBytes) {\n const sizeInKB = fileSizeInBytes / 1024;\n\n if (sizeInKB > 500) {\n quality = Math.min(baseQuality, 25);\n effort = 9;\n pngCompression = 9;\n } else if (sizeInKB > 300) {\n quality = Math.min(baseQuality, 30);\n effort = 8;\n pngCompression = 9;\n } else if (sizeInKB > 150) {\n quality = Math.min(baseQuality, 35);\n effort = 7;\n pngCompression = 8;\n } else if (sizeInKB > 90) {\n quality = Math.min(baseQuality, 40);\n effort = 6;\n pngCompression = 8;\n } else if (sizeInKB > 50) {\n quality = Math.min(baseQuality, 50);\n effort = 5;\n pngCompression = 7;\n }\n }\n\n return {\n quality: Math.max(1, Math.min(100, quality)),\n effort,\n pngCompression,\n ...(width && height && { width, height, fit: resolvedFit }),\n ...(resolvedPosition && { position: resolvedPosition }),\n };\n};\n\n// Legacy alias for backward compatibility\nexport const getQualitySettings = (fileSizeInBytes: number | undefined, qualityPreset: string | undefined) =>\n getImageSettings(fileSizeInBytes, qualityPreset, undefined, undefined);\n","import crypto from 'crypto';\r\n\r\n/**\r\n * Constant-time string comparison to prevent timing attacks\r\n */\r\nexport function constantTimeCompare(a: string, b: string): boolean {\r\n\tif (a.length !== b.length) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tlet result = 0;\r\n\tfor (let i = 0; i < a.length; i++) {\r\n\t\tresult |= a.charCodeAt(i) ^ b.charCodeAt(i);\r\n\t}\r\n\r\n\treturn result === 0;\r\n}\r\n\r\n/**\r\n * Safe error message that doesn't leak sensitive information\r\n */\r\nexport function getSafeErrorMessage(error: unknown): string {\r\n\tif (error instanceof Error) {\r\n\t\t// Filter out sensitive patterns (case-insensitive)\r\n\t\tconst message = error.message.toLowerCase();\r\n\r\n\t\t// Don't expose database errors\r\n\t\tif (message.includes('mongo')) {\r\n\t\t\treturn 'Database operation failed';\r\n\t\t}\r\n\r\n\t\t// Don't expose file paths\r\n\t\tif (message.includes('/') || message.includes('\\\\')) {\r\n\t\t\treturn 'File operation failed';\r\n\t\t}\r\n\r\n\t\t// Don't expose validation details from internal libraries\r\n\t\tif (message.includes('validation') || message.includes('cast')) {\r\n\t\t\treturn 'Invalid input';\r\n\t\t}\r\n\r\n\t\t// Generic safe messages\r\n\t\treturn 'Operation failed';\r\n\t}\r\n\r\n\treturn 'Internal server error';\r\n}\r\n\r\n/**\r\n * Validate and sanitize Content-Disposition filename\r\n */\r\nexport function sanitizeContentDispositionFilename(filename: string): string {\r\n\t// Remove any path components\r\n\tconst basename = filename.replace(/^.*[\\\\\\/]/, '');\r\n\r\n\t// Remove or encode dangerous characters\r\n\treturn basename\r\n\t\t.replace(/[\"\\r\\n]/g, '')\r\n\t\t.replace(/[^\\x20-\\x7E]/g, '') // Remove non-printable ASCII\r\n\t\t.slice(0, 255);\r\n}\r\n","import fs from 'fs';\nimport path from 'path';\nimport mongoose from 'mongoose';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport { getDriveConfig } from '@/server/config';\nimport { extractImageMetadata, computeFileHash } from '@/server/utils';\nimport type { TStorageProvider } from '@/types/server/storage';\nimport type { IDatabaseDriveDocument } from '@/server/database/mongoose/schema/drive';\nimport ffmpeg from 'fluent-ffmpeg';\nimport sharp from 'sharp';\n\n/**\n * Generate a placeholder thumbnail for unsupported file types\n * Creates a simple 300x300 gray image with file type label\n */\nconst generatePlaceholderThumbnail = async (outputPath: string, mimeType: string): Promise<void> => {\n // Extract file type from mime (e.g., \"image/x-icon\" -> \"ICO\", \"video/mp4\" -> \"MP4\")\n const typeParts = mimeType.split('/');\n const subtype = typeParts[1] || 'file';\n const label = subtype.replace(/^x-/, '').toUpperCase().slice(0, 6); // Max 6 chars\n\n // Create a simple SVG placeholder and convert to WebP\n const svg = `\n <svg width=\"300\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"300\" height=\"300\" fill=\"#e5e7eb\"/>\n <text x=\"150\" y=\"140\" text-anchor=\"middle\" font-family=\"system-ui, sans-serif\" font-size=\"48\" fill=\"#6b7280\">${label}</text>\n <text x=\"150\" y=\"180\" text-anchor=\"middle\" font-family=\"system-ui, sans-serif\" font-size=\"16\" fill=\"#9ca3af\">Preview unavailable</text>\n </svg>\n `;\n\n await sharp(Buffer.from(svg))\n .resize(300, 300)\n .toFormat('webp', { quality: 80 })\n .toFile(outputPath);\n};\n\n\nexport const LocalStorageProvider: TStorageProvider = {\n name: 'LOCAL',\n\n sync: async (folderId, owner, accountId) => {\n // No-op for local storage as DB is the source of truth\n },\n\n search: async (query, owner, accountId) => {\n // No-op for local storage as DB text search handles it\n },\n\n getQuota: async (owner, accountId, configuredQuotaInBytes) => {\n const config = getDriveConfig();\n const isRootMode = config.mode === 'ROOT';\n\n // In ROOT mode, return total storage used across all users\n const match: Record<string, unknown> = {\n 'information.type': 'FILE',\n trashedAt: null,\n 'provider.type': 'LOCAL',\n storageAccountId: accountId || null\n };\n\n // Only filter by owner in NORMAL mode\n if (!isRootMode) {\n match.owner = owner;\n }\n\n // Calculate storage used from DB - only count LOCAL provider files\n const result = await Drive.aggregate([\n { $match: match },\n { $group: { _id: null, total: { $sum: '$information.sizeInBytes' } } }\n ]);\n const usedInBytes = result[0]?.total || 0;\n\n // In ROOT mode, return unlimited quota\n if (isRootMode) {\n return { usedInBytes, quotaInBytes: Number.MAX_SAFE_INTEGER };\n }\n\n // Use configured quota from user's information callback (required)\n return { usedInBytes, quotaInBytes: configuredQuotaInBytes ?? 0 };\n },\n\n openStream: async (item: IDatabaseDriveDocument, accountId?: string) => {\n if (item.information.type !== 'FILE') throw new Error('Could not open local file: folders cannot be streamed');\n const storagePath = getDriveConfig().storage.path;\n const filePath = path.join(storagePath, 'file', item._id.toString(), 'data.bin');\n\n if (!fs.existsSync(filePath)) {\n throw new Error('Could not open local file: it is missing from disk');\n }\n\n const stat = fs.statSync(filePath);\n const stream = fs.createReadStream(filePath);\n\n return {\n stream,\n mime: item.information.mime,\n size: stat.size,\n };\n },\n\n getThumbnail: async (item: IDatabaseDriveDocument, accountId?: string) => {\n if (item.information.type !== 'FILE') throw new Error('No preview available: folders do not have thumbnails');\n\n const storagePath = getDriveConfig().storage.path;\n const fileDir = path.join(storagePath, 'file', item._id.toString());\n const originalPath = path.join(fileDir, 'data.bin');\n const thumbDir = path.join(fileDir, 'cache');\n const thumbPath = path.join(thumbDir, 'thumbnail.webp');\n\n if (!fs.existsSync(originalPath)) throw new Error('Could not generate preview: the original file is missing');\n\n if (fs.existsSync(thumbPath)) {\n return fs.createReadStream(thumbPath);\n }\n\n // Generate thumbnail\n if (!fs.existsSync(thumbDir)) fs.mkdirSync(thumbDir, { recursive: true });\n\n if (item.information.mime.startsWith('image/')) {\n try {\n await sharp(originalPath).resize(300, 300, { fit: 'inside' }).toFormat('webp', { quality: 80 }).toFile(thumbPath);\n } catch (err) {\n // Unsupported format (ICO, HEIC, SVG, etc.) - generate placeholder\n console.warn(`[next-drive] Thumbnail generation failed for ${item.information.mime}, using placeholder`);\n await generatePlaceholderThumbnail(thumbPath, item.information.mime);\n }\n } else if (item.information.mime.startsWith('video/')) {\n try {\n await new Promise((resolve, reject) => {\n ffmpeg(originalPath)\n .screenshots({\n count: 1,\n folder: path.dirname(thumbPath),\n filename: path.basename(thumbPath),\n size: '300x?',\n })\n .on('end', resolve)\n .on('error', reject);\n });\n } catch (err) {\n console.warn(`[next-drive] Video thumbnail generation failed, using placeholder`);\n await generatePlaceholderThumbnail(thumbPath, item.information.mime);\n }\n } else {\n // Unsupported type - generate placeholder\n await generatePlaceholderThumbnail(thumbPath, item.information.mime);\n }\n\n return fs.createReadStream(thumbPath);\n },\n\n createFolder: async (name, parentId, owner, accountId) => {\n // Just DB operation for local folders (virtual)\n const getNextOrderValue = async (owner: Record<string, unknown> | null): Promise<number> => {\n const lastItem = await Drive.findOne({ owner }, {}, { sort: { order: -1 } });\n return lastItem ? lastItem.order + 1 : 0;\n };\n\n const folder = new Drive({\n owner,\n name,\n parentId: parentId === 'root' || !parentId ? null : parentId,\n order: await getNextOrderValue(owner),\n provider: { type: 'LOCAL' },\n information: { type: 'FOLDER' },\n status: 'READY',\n });\n await folder.save();\n return folder.toClient();\n },\n\n uploadFile: async (drive, filePath, accountId) => {\n if (drive.information.type !== 'FILE') throw new Error('Could not save local file: invalid file record');\n\n const storagePath = getDriveConfig().storage.path;\n const destDir = path.join(storagePath, 'file', String(drive._id));\n const destPath = path.join(destDir, 'data.bin');\n\n // Ensure source file exists\n if (!fs.existsSync(filePath)) {\n throw new Error('Could not save local file: the uploaded data is missing');\n }\n\n // Create destination directory if it doesn't exist\n if (!fs.existsSync(destDir)) {\n fs.mkdirSync(destDir, { recursive: true });\n }\n\n // Move file: try rename first (fast), fallback to copy+delete for cross-device\n try {\n fs.renameSync(filePath, destPath);\n } catch (err: unknown) {\n // EXDEV: cross-device link not permitted - use copy+delete instead\n if (err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'EXDEV') {\n fs.copyFileSync(filePath, destPath);\n fs.unlinkSync(filePath);\n } else {\n throw err;\n }\n }\n\n // Verify destination file exists after move/copy\n if (!fs.existsSync(destPath)) {\n throw new Error('Could not save local file: writing to storage failed');\n }\n\n // Verify file size matches expected\n const destStats = fs.statSync(destPath);\n if (destStats.size !== drive.information.sizeInBytes) {\n // Cleanup corrupted file\n fs.unlinkSync(destPath);\n throw new Error('Could not save local file: the stored data was incomplete (size mismatch)');\n }\n\n drive.status = 'READY';\n drive.information.path = path.join('file', String(drive._id), 'data.bin');\n drive.information.hash = await computeFileHash(destPath);\n\n if (drive.information.mime.startsWith('image/')) {\n const meta = await extractImageMetadata(destPath);\n if (meta) {\n drive.information.width = meta.width;\n drive.information.height = meta.height;\n }\n }\n\n await drive.save();\n return drive.toClient();\n },\n\n delete: async (ids, owner, accountId) => {\n const items = await Drive.find({ _id: { $in: ids }, owner }).lean();\n\n // ** Helper to recursively get all children\n type TDriveItem = { _id: mongoose.Types.ObjectId; information: { type: string; path?: string } };\n\n const getAllChildren = async (folderIds: string[]): Promise<TDriveItem[]> => {\n const children = await Drive.find({ parentId: { $in: folderIds }, owner }).lean();\n if (children.length === 0) return [];\n\n const subFolderIds = children\n .filter(c => c.information.type === 'FOLDER')\n .map(c => c._id.toString());\n\n const subChildren = await getAllChildren(subFolderIds);\n return [...children, ...subChildren] as TDriveItem[];\n };\n\n const folderIds = items.filter(i => i.information.type === 'FOLDER').map(i => i._id.toString());\n const allChildren = await getAllChildren(folderIds);\n const allItemsToDelete = [...items, ...allChildren] as TDriveItem[];\n\n // ** Delete files from disk\n for (const item of allItemsToDelete) {\n if (item.information.type === 'FILE' && item.information.path) {\n // ** Delete entire file directory (includes cache)\n const fileDir = path.join(getDriveConfig().storage.path, 'file', item._id.toString());\n if (fs.existsSync(fileDir)) {\n fs.rmSync(fileDir, { recursive: true, force: true });\n }\n }\n }\n\n // ** Delete from DB\n await Drive.deleteMany({ _id: { $in: allItemsToDelete.map(i => i._id) } });\n },\n\n trash: async (ids, owner, accountId) => {\n // No-op for local, handled by DB update in index.ts\n },\n\n syncTrash: async (owner, accountId) => {\n // No-op for local\n },\n\n untrash: async (ids, owner, accountId) => {\n // No-op for local\n },\n\n rename: async (id, newName, owner, accountId) => {\n const item = await Drive.findOneAndUpdate({ _id: id, owner }, { name: newName }, { new: true });\n if (!item) throw new Error('Could not rename: the item no longer exists');\n return item.toClient();\n },\n\n move: async (id, newParentId, owner, accountId) => {\n const item = await Drive.findOne({ _id: id, owner });\n if (!item) throw new Error('Could not move: the item no longer exists');\n\n // ** Update DB\n item.parentId = newParentId === 'root' || !newParentId ? null : new mongoose.Types.ObjectId(newParentId);\n\n // ** For LOCAL storage, physical path is ID-based: file/{ID}/data.bin\n // ** Folder hierarchy is virtual (in DB only), so move is just a DB update\n await item.save();\n return item.toClient();\n },\n\n revokeToken: async (owner, accountId) => {\n // No-op\n },\n};\n","// ** Mongoose Storage Account Schema\nimport type { TDatabaseStorageAccount, TDatabaseStorageAccountMetadata } from '@/types/lib/database/storage/account';\nimport mongoose, { Schema, type Document, type Model, type Types } from 'mongoose';\n\nexport interface IDatabaseStorageAccountDocument extends Document {\n owner: Record<string, unknown> | null;\n name: string;\n metadata: TDatabaseStorageAccountMetadata;\n createdAt: Date;\n\n toClient: () => Promise<TDatabaseStorageAccount>;\n}\n\n// ** Schema definition\nconst StorageAccountSchema: Schema = new Schema<IDatabaseStorageAccountDocument>(\n {\n owner: { type: Schema.Types.Mixed, default: null },\n name: { type: String, required: true },\n metadata: {\n provider: { type: String, enum: ['GOOGLE'], required: true },\n google: {\n email: { type: String, required: true },\n credentials: { type: Schema.Types.Mixed, required: true },\n },\n },\n createdAt: { type: Date, default: Date.now },\n },\n { minimize: false }\n);\n\n// ** Indexes\nStorageAccountSchema.index({ owner: 1, 'metadata.provider': 1 });\nStorageAccountSchema.index({ owner: 1, 'metadata.google.email': 1 });\n\n// ** Method: toClient\nStorageAccountSchema.method<IDatabaseStorageAccountDocument>('toClient', async function (): Promise<TDatabaseStorageAccount> {\n const data = this.toJSON<IDatabaseStorageAccountDocument>();\n\n return {\n id: String(data._id),\n owner: data.owner,\n name: data.name,\n metadata: data.metadata,\n createdAt: data.createdAt,\n };\n});\n\nconst StorageAccount: Model<IDatabaseStorageAccountDocument> = mongoose.models.StorageAccount || mongoose.model<IDatabaseStorageAccountDocument>('StorageAccount', StorageAccountSchema);\n\nexport default StorageAccount;\n","import fs from 'fs';\nimport path from 'path';\nimport { google, type drive_v3 } from 'googleapis';\nimport { Readable } from 'stream';\nimport mongoose from 'mongoose';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport StorageAccount from '@/server/database/mongoose/schema/storage/account';\nimport { getDriveConfig } from '@/server/config';\nimport type { TStorageProvider, TDriveQuota } from '@/types/server/storage';\nimport type { IDatabaseDriveDocument } from '@/server/database/mongoose/schema/drive';\nimport type { TDatabaseDrive } from '@/types/lib/database/drive';\n\nconst createAuthClient = async (owner: Record<string, unknown> | null, accountId?: string) => {\n // ** Get credentials from StorageAccount\n const query: Record<string, unknown> = { owner, 'metadata.provider': 'GOOGLE' };\n if (accountId) query._id = accountId;\n\n // ** If multiple accounts and no accountId, pick first one\n const account = await StorageAccount.findOne(query);\n if (!account) throw new Error('Could not reach Google Drive: account not connected');\n\n const config = getDriveConfig();\n const { clientId, clientSecret, redirectUri } = config.storage?.google || {};\n\n if (!clientId || !clientSecret) throw new Error('Could not reach Google Drive: Google credentials are not configured on the server');\n\n const oAuth2Client = new google.auth.OAuth2(clientId, clientSecret, redirectUri);\n\n // ** Verify it's a google account and metadata exists\n if (account.metadata.provider !== 'GOOGLE' || !account.metadata.google) {\n throw new Error('Could not reach Google Drive: account data is invalid, please reconnect');\n }\n\n oAuth2Client.setCredentials(account.metadata.google.credentials as Parameters<typeof oAuth2Client.setCredentials>[0]);\n\n // ** Update tokens listener\n oAuth2Client.on('tokens', async tokens => {\n if (tokens.refresh_token) {\n account.metadata.google.credentials = { ...account.metadata.google.credentials, ...tokens };\n account.markModified('metadata');\n await account.save();\n }\n });\n\n return { client: oAuth2Client, accountId: account._id };\n};\n\nexport const GoogleDriveProvider: TStorageProvider = {\n name: 'GOOGLE',\n\n sync: async (folderId, owner, accountId) => {\n const { client, accountId: foundAccountId } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n // Resolve Google Folder ID\n let googleParentId = 'root';\n if (folderId && folderId !== 'root') {\n const folder = await Drive.findOne({ _id: folderId, owner });\n if (folder && folder.provider?.google?.id) {\n googleParentId = folder.provider.google.id;\n } else {\n return;\n }\n }\n\n // ** List files from Google with pagination\n let pageToken: string | undefined = undefined;\n const allSyncedGoogleIds = new Set<string>();\n\n do {\n const listParams: drive_v3.Params$Resource$Files$List = {\n q: `'${googleParentId}' in parents and trashed = false`,\n fields: 'nextPageToken, files(id, name, mimeType, size, webViewLink, iconLink, thumbnailLink, createdTime)',\n pageSize: 1000,\n pageToken,\n };\n const res = await drive.files.list(listParams);\n const responseData = res.data;\n\n pageToken = responseData.nextPageToken ?? undefined;\n const files = responseData.files ?? [];\n\n // Upsert to MongoDB\n for (const file of files) {\n if (!file.id || !file.name || !file.mimeType) continue;\n\n // Track ID\n allSyncedGoogleIds.add(file.id);\n\n // RELAXED FILTER: Allow Google Docs (application/vnd.google-apps.*)\n const isFolder = file.mimeType === 'application/vnd.google-apps.folder';\n // if (!isFolder && file.mimeType.startsWith('application/vnd.google-apps.')) continue; // REMOVED FILTER\n\n const sizeInBytes = file.size ? parseInt(file.size) : 0;\n\n // Construct update data\n const updateData = {\n name: file.name,\n storageAccountId: foundAccountId,\n parentId: folderId === 'root' ? null : folderId,\n information: {\n type: isFolder ? 'FOLDER' : 'FILE',\n sizeInBytes,\n mime: file.mimeType,\n path: '',\n },\n provider: {\n type: 'GOOGLE',\n google: {\n id: file.id,\n webViewLink: file.webViewLink,\n iconLink: file.iconLink,\n thumbnailLink: file.thumbnailLink,\n },\n },\n status: 'READY',\n trashedAt: null,\n };\n\n // Use source file's createdTime for createdAt on insert\n const insertData = file.createdTime ? { createdAt: new Date(file.createdTime) } : {};\n\n await Drive.findOneAndUpdate(\n {\n owner,\n 'provider.google.id': file.id,\n 'provider.type': 'GOOGLE',\n },\n { $set: updateData, $setOnInsert: insertData },\n { upsert: true, new: true, setDefaultsOnInsert: true },\n );\n }\n } while (pageToken);\n\n // ** Handle deletions - remove items in DB that were NOT in the gathered list\n const dbItems = await Drive.find({\n owner,\n storageAccountId: foundAccountId,\n parentId: folderId === 'root' ? null : folderId,\n 'provider.type': 'GOOGLE',\n });\n\n for (const item of dbItems) {\n // If item has a google ID and it wasn't seen in the sync list -> trash it\n if (item.provider?.google?.id && !allSyncedGoogleIds.has(item.provider.google.id)) {\n item.trashedAt = new Date();\n await item.save();\n }\n }\n },\n\n syncTrash: async (owner, accountId) => {\n const { client, accountId: foundAccountId } = await createAuthClient(owner, accountId);\n const driveApi = google.drive({ version: 'v3', auth: client });\n\n // ** Helper to fetch trashed files with pagination\n const fetchTrashedFiles = async (pageToken?: string) => {\n return driveApi.files.list({\n q: 'trashed = true',\n fields: 'nextPageToken, files(id, name, mimeType, size, webViewLink, iconLink, thumbnailLink, createdTime)',\n pageSize: 100,\n pageToken,\n });\n };\n\n // ** List trashed files from Google with pagination\n let nextToken: string | undefined = undefined;\n\n do {\n const listResult = await fetchTrashedFiles(nextToken);\n const files = listResult.data.files || [];\n\n for (const file of files) {\n if (!file.id || !file.name || !file.mimeType) continue;\n\n // ** RELAXED FILTER: Allow Google Docs (application/vnd.google-apps.*)\n const isFolder = file.mimeType === 'application/vnd.google-apps.folder';\n\n const sizeInBytes = file.size ? parseInt(file.size) : 0;\n\n // ** Use source file's createdTime for createdAt on insert\n const insertData = file.createdTime ? { createdAt: new Date(file.createdTime) } : {};\n\n await Drive.findOneAndUpdate(\n { owner, 'provider.google.id': file.id, 'provider.type': 'GOOGLE' },\n {\n $set: {\n name: file.name,\n storageAccountId: foundAccountId,\n information: {\n type: isFolder ? 'FOLDER' : 'FILE',\n sizeInBytes,\n mime: file.mimeType,\n path: '',\n },\n provider: {\n type: 'GOOGLE',\n google: {\n id: file.id,\n webViewLink: file.webViewLink,\n iconLink: file.iconLink,\n thumbnailLink: file.thumbnailLink,\n },\n },\n trashedAt: new Date(),\n },\n $setOnInsert: insertData,\n },\n { upsert: true, setDefaultsOnInsert: true },\n );\n }\n\n // ** Update pagination state\n nextToken = listResult.data.nextPageToken ?? undefined;\n } while (nextToken);\n },\n\n search: async (query, owner, accountId) => {\n const { client, accountId: foundAccountId } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n // Google Search Query\n // name contains 'query'\n const res = await drive.files.list({\n q: `name contains '${query}' and trashed = false`,\n fields: 'files(id, name, mimeType, size, parents, webViewLink, iconLink, thumbnailLink, createdTime)',\n pageSize: 50,\n });\n\n const files = res.data.files || [];\n\n // Upsert results\n // Note: We might not know the local parentId for these items if we haven't synced their parents.\n // This makes it tricky. If we just upsert with parentId=null (root), they show up in root, which is confusing.\n // Option: Don't change parentId if exists. If new, maybe leave parentId null/undefined but we need it.\n // Strategy: Just update existing items metadata?\n // OR: \"Search\" just returns items without persisting parent structure?\n // But our UI relies on DB.\n // If we upsert new items from search, we must assign a parent.\n // Typically we can't assign accurate local parent ID without traversing up.\n // Compromise: Update properties of existing items. Ignore new items?\n // OR: Just let `list` handle creation. Search only works on things we've synced?\n // NO, user wants to find remote files.\n // Allow creating with parentId = null (root) for now? Or keep them \"orphaned\" (parentId: undefined) if that works?\n // Drive schema requires parentId? default null.\n // Let's skip upserting NEW items from search for now to avoid mess.\n // Only update existing.\n // Wait, if I search for \"Report\", I want to see \"Report.pdf\" even if I never opened the folder.\n // This implies I need to sync it.\n // For now, I will NOT upsert in search to keep safety. search only funds synced items.\n // Re-evaluating: The prompt said \"Search... mapping user queries to Google's q syntax\".\n // This implies meaningful results.\n // Let's implement basics: Sync results to DB. Parent = null (Root) if unknown.\n // Users can then \"Go to location\" -> might fail if path unknown.\n // Just upserting with `parentId: null` puts them in root.\n // I will omit parentId in update, so it keeps existing. If new, it defaults to null (Root).\n // This is acceptable behavior for \"All files\" view or similar.\n\n for (const file of files) {\n if (!file.id || !file.name) continue;\n const isFolder = file.mimeType === 'application/vnd.google-apps.folder';\n if (!isFolder && file.mimeType?.startsWith('application/vnd.google-apps.')) continue;\n\n const sizeInBytes = file.size ? parseInt(file.size) : 0;\n\n // Use source file's createdTime for createdAt on insert\n const insertData = file.createdTime ? { createdAt: new Date(file.createdTime) } : {};\n\n await Drive.findOneAndUpdate(\n { owner, 'provider.google.id': file.id, 'metadata.type': 'GOOGLE' },\n {\n $set: {\n name: file.name,\n storageAccountId: foundAccountId,\n information: {\n type: isFolder ? 'FOLDER' : 'FILE',\n sizeInBytes,\n mime: file.mimeType,\n path: '',\n },\n metadata: {\n type: 'GOOGLE',\n },\n provider: {\n google: {\n id: file.id,\n webViewLink: file.webViewLink,\n iconLink: file.iconLink,\n thumbnailLink: file.thumbnailLink,\n },\n },\n // Don't overwrite parentId if it exists.\n // New items will default to null (Root) via schema default\n },\n $setOnInsert: insertData,\n },\n { upsert: true, setDefaultsOnInsert: true },\n );\n }\n },\n\n getQuota: async (owner, accountId, _configuredQuotaInBytes) => {\n const config = getDriveConfig();\n const isRootMode = config.mode === 'ROOT';\n\n // In ROOT mode, calculate from DB and return unlimited quota\n if (isRootMode) {\n const result = await Drive.aggregate([\n {\n $match: {\n 'information.type': 'FILE',\n trashedAt: null,\n 'provider.type': 'GOOGLE',\n storageAccountId: accountId || null,\n },\n },\n { $group: { _id: null, total: { $sum: '$information.sizeInBytes' } } },\n ]);\n const usedInBytes = result[0]?.total || 0;\n return { usedInBytes, quotaInBytes: Number.MAX_SAFE_INTEGER };\n }\n\n // Google Drive uses its own quota from the API, ignores configured quota\n try {\n const { client } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n const res = await drive.about.get({ fields: 'storageQuota' });\n return {\n usedInBytes: parseInt(res.data.storageQuota?.usage || '0'),\n quotaInBytes: parseInt(res.data.storageQuota?.limit || '0'),\n };\n } catch {\n return { usedInBytes: 0, quotaInBytes: 0 };\n }\n },\n\n openStream: async (item: IDatabaseDriveDocument, accountId?: string) => {\n const { client } = await createAuthClient(item.owner, accountId || item.storageAccountId?.toString());\n const drive = google.drive({ version: 'v3', auth: client });\n\n if (!item.provider?.google?.id) throw new Error('Could not open Google Drive file: its Google file ID is missing');\n\n // ** Check if we can stream functionality\n if (item.information.type === 'FOLDER') throw new Error('Could not open Google Drive file: folders cannot be streamed');\n\n const res = await drive.files.get(\n { fileId: item.provider.google.id, alt: 'media' },\n { responseType: 'stream' }\n );\n\n return {\n stream: res.data as Readable,\n mime: item.information.mime,\n size: item.information.sizeInBytes,\n };\n },\n\n getThumbnail: async (item: IDatabaseDriveDocument, accountId?: string) => {\n const config = getDriveConfig();\n const storagePath = config.storage.path;\n const thumbDir = path.join(storagePath, 'file', item._id.toString(), 'cache');\n const thumbPath = path.join(thumbDir, 'thumbnail.webp');\n\n // ** Return cached thumbnail if exists\n if (fs.existsSync(thumbPath)) {\n return fs.createReadStream(thumbPath);\n }\n\n // ** Fetch from Google\n const { client } = await createAuthClient(item.owner, accountId || item.storageAccountId?.toString());\n if (!item.provider?.google?.thumbnailLink) throw new Error('No preview available for this Google Drive file');\n\n const res = await client.request<Readable>({ url: item.provider.google.thumbnailLink, responseType: 'stream' });\n\n // ** Cache the thumbnail\n if (!fs.existsSync(thumbDir)) {\n fs.mkdirSync(thumbDir, { recursive: true });\n }\n\n const tempPath = `${thumbPath}.tmp`;\n const writeStream = fs.createWriteStream(tempPath);\n\n await new Promise<void>((resolve, reject) => {\n (res.data as Readable).pipe(writeStream);\n writeStream.on('finish', resolve);\n writeStream.on('error', reject);\n });\n\n // ** Rename temp to final\n try {\n fs.renameSync(tempPath, thumbPath);\n } catch {\n // If rename fails, cleanup and return stream from Google\n fs.unlinkSync(tempPath);\n }\n\n // ** Return the cached file\n if (fs.existsSync(thumbPath)) {\n return fs.createReadStream(thumbPath);\n }\n\n // ** Fallback: refetch from Google\n const refetch = await client.request<Readable>({ url: item.provider.google.thumbnailLink, responseType: 'stream' });\n return refetch.data as Readable;\n },\n\n createFolder: async (name, parentId, owner, accountId) => {\n const { client, accountId: foundAccountId } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n let googleParentId = 'root';\n if (parentId && parentId !== 'root') {\n const parent = await Drive.findOne({ _id: parentId, owner });\n if (parent?.provider?.google?.id) googleParentId = parent.provider.google.id;\n }\n\n const res = await drive.files.create({\n requestBody: {\n name,\n mimeType: 'application/vnd.google-apps.folder',\n parents: [googleParentId],\n },\n fields: 'id, name, mimeType, webViewLink, iconLink',\n });\n\n const file = res.data;\n if (!file.id) throw new Error('Could not create folder on Google Drive');\n\n // Create local record\n const folder = new Drive({\n owner,\n name: file.name,\n parentId: parentId === 'root' || !parentId ? null : parentId,\n provider: {\n type: 'GOOGLE',\n google: {\n id: file.id,\n webViewLink: file.webViewLink,\n iconLink: file.iconLink,\n },\n },\n storageAccountId: foundAccountId,\n information: { type: 'FOLDER' },\n status: 'READY',\n });\n await folder.save();\n return folder.toClient();\n },\n\n uploadFile: async (drive, filePath, accountId) => {\n if (drive.information.type !== 'FILE') throw new Error('Could not upload to Google Drive: invalid file record');\n\n const { client } = await createAuthClient(drive.owner, accountId || drive.storageAccountId?.toString());\n const googleDrive = google.drive({ version: 'v3', auth: client });\n\n let googleParentId = 'root';\n if (drive.parentId) {\n const parent = await Drive.findById(drive.parentId);\n if (parent?.provider?.google?.id) googleParentId = parent.provider.google.id;\n }\n\n try {\n const res = await googleDrive.files.create({\n requestBody: {\n name: drive.name,\n parents: [googleParentId],\n mimeType: drive.information.mime,\n },\n media: {\n mimeType: drive.information.mime,\n body: fs.createReadStream(filePath),\n },\n fields: 'id, name, mimeType, webViewLink, iconLink, thumbnailLink, size',\n });\n\n const gFile = res.data;\n if (!gFile.id) throw new Error('Could not upload to Google Drive: no file was created');\n\n // ** Update Drive record\n drive.status = 'READY';\n drive.provider = {\n type: 'GOOGLE',\n google: {\n id: gFile.id,\n webViewLink: gFile.webViewLink || undefined,\n iconLink: gFile.iconLink || undefined,\n thumbnailLink: gFile.thumbnailLink || undefined,\n },\n };\n\n // ** Note: We don't delete the temp file here, index.ts handles cleanup\n } catch (error) {\n drive.status = 'FAILED';\n console.error('[next-drive] Google Upload Error:', error);\n throw error;\n }\n\n await drive.save();\n return drive.toClient();\n },\n\n delete: async (ids, owner, accountId) => {\n const { client } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n const items = await Drive.find({ _id: { $in: ids }, owner });\n\n for (const item of items) {\n if (item.provider?.google?.id) {\n try {\n await drive.files.delete({ fileId: item.provider.google.id });\n } catch (e) {\n console.error('Failed to delete Google file', e);\n }\n }\n }\n\n await Drive.deleteMany({ _id: { $in: ids } });\n },\n\n trash: async (ids, owner, accountId) => {\n const { client } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n const items = await Drive.find({ _id: { $in: ids }, owner });\n\n for (const item of items) {\n if (item.provider?.google?.id) {\n try {\n await drive.files.update({\n fileId: item.provider.google.id,\n requestBody: { trashed: true },\n });\n } catch (e) {\n console.error('Failed to trash Google file', e);\n }\n }\n }\n },\n\n untrash: async (ids, owner, accountId) => {\n const { client } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n const items = await Drive.find({ _id: { $in: ids }, owner });\n\n for (const item of items) {\n if (item.provider?.google?.id) {\n try {\n await drive.files.update({\n fileId: item.provider.google.id,\n requestBody: { trashed: false },\n });\n } catch (e) {\n console.error('Failed to restore Google file', e);\n }\n }\n }\n },\n\n rename: async (id, newName, owner, accountId) => {\n const { client } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n const item = await Drive.findOne({ _id: id, owner });\n if (!item || !item.provider?.google?.id) throw new Error('Could not rename on Google Drive: item not found or not synced');\n\n await drive.files.update({\n fileId: item.provider.google.id,\n requestBody: { name: newName },\n });\n\n item.name = newName;\n await item.save();\n return item.toClient();\n },\n\n move: async (id, newParentId, owner, accountId) => {\n const { client, accountId: foundAccountId } = await createAuthClient(owner, accountId);\n const drive = google.drive({ version: 'v3', auth: client });\n\n // Get Item\n const item = await Drive.findOne({ _id: id, owner });\n if (!item || !item.provider?.google?.id) throw new Error('Could not move on Google Drive: item not found or not synced');\n\n // Resolve Old Parent Google ID\n let previousGoogleParentId: string | undefined = undefined;\n if (item.parentId) {\n const oldParent = await Drive.findOne({ _id: item.parentId, owner });\n if (oldParent && oldParent.provider?.google?.id) {\n previousGoogleParentId = oldParent.provider.google.id;\n }\n } else {\n // If parentId is null (root), finding previous parent is tricky without querying Google\n // But usually we don't need to specify removeParents if we don't care about multi-parenting?\n // Actually, in Drive API v3, moving requires removeParents if you want to 'move' and not 'add to'.\n // Let's query parents from Google to be safe\n try {\n const gFile = await drive.files.get({ fileId: item.provider.google.id, fields: 'parents' });\n if (gFile.data.parents && gFile.data.parents.length > 0) {\n previousGoogleParentId = gFile.data.parents.join(',');\n }\n } catch (e) {\n console.warn('Could not fetch parents for move', e);\n }\n }\n\n // Resolve New Parent Google ID\n let newGoogleParentId = 'root'; // User's root (maybe specific root folder if we support that?)\n // For now, assume 'root' maps to Drive root (or myDrive)\n if (newParentId && newParentId !== 'root') {\n const newParent = await Drive.findOne({ _id: newParentId, owner });\n if (!newParent || !newParent.provider?.google?.id) throw new Error('Could not move on Google Drive: target folder not found');\n newGoogleParentId = newParent.provider.google.id;\n }\n\n // Call Google API\n await drive.files.update({\n fileId: item.provider.google.id,\n addParents: newGoogleParentId,\n removeParents: previousGoogleParentId,\n fields: 'id, parents',\n });\n\n // Update DB\n item.parentId = newParentId === 'root' || !newParentId ? null : new mongoose.Types.ObjectId(newParentId);\n await item.save();\n\n return item.toClient();\n },\n\n revokeToken: async (owner, accountId) => {\n if (!accountId) return; // ** Need specific account to revoke\n const { client } = await createAuthClient(owner, accountId);\n const account = await StorageAccount.findById(accountId);\n if (account?.metadata?.provider === 'GOOGLE' && account.metadata.google?.credentials) {\n const creds = account.metadata.google.credentials as Record<string, unknown>;\n if (typeof creds === 'object' && 'access_token' in creds && typeof creds.access_token === 'string') {\n await client.revokeToken(creds.access_token);\n }\n }\n },\n};\n","import type { NextApiRequest, NextApiResponse } from 'next';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport sharp from 'sharp';\nimport { getDriveConfig } from '@/server/config';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport { getImageSettings } from '@/server/utils';\nimport { sanitizeContentDispositionFilename } from '@/server/security/crypto-utils';\nimport { LocalStorageProvider } from '@/server/storage-adapters/local';\nimport { GoogleDriveProvider } from '@/server/storage-adapters/google';\n\nexport const handlePublicAction = async (\n req: NextApiRequest,\n res: NextApiResponse,\n action: string,\n config: ReturnType<typeof getDriveConfig>\n): Promise<boolean> => {\n if (action !== 'serve' && action !== 'thumbnail') {\n return false;\n }\n\n try {\n const { id, token } = req.query;\n if (!id || typeof id !== 'string') {\n res.status(400).json({ status: 400, message: 'Could not open file: missing or invalid file ID' });\n return true;\n }\n\n const drive = await Drive.findById(id);\n if (!drive) {\n res.status(404).json({ status: 404, message: 'File not found or no longer available' });\n return true;\n }\n\n if (config.security?.signedUrls?.enabled) {\n if (!token || typeof token !== 'string') {\n res.status(401).json({ status: 401, message: 'Access denied: this link is missing its access token' });\n return true;\n }\n\n try {\n const decoded = Buffer.from(token, 'base64url').toString();\n const [expiryStr, signature] = decoded.split(':');\n const expiry = parseInt(expiryStr, 10);\n\n if (Date.now() / 1000 > expiry) {\n res.status(401).json({ status: 401, message: 'Access denied: this link has expired' });\n return true;\n }\n\n const { secret } = config.security.signedUrls;\n const expectedSignature = crypto.createHmac('sha256', secret)\n .update(`${id}:${expiry}`)\n .digest('hex');\n\n if (signature !== expectedSignature) {\n res.status(401).json({ status: 401, message: 'Access denied: this link\\'s access token is invalid' });\n return true;\n }\n } catch {\n res.status(401).json({ status: 401, message: 'Access denied: this link\\'s access token is malformed' });\n return true;\n }\n }\n\n const itemProvider = drive.provider?.type === 'GOOGLE' ? GoogleDriveProvider : LocalStorageProvider;\n const itemAccountId = drive.storageAccountId ? drive.storageAccountId.toString() : undefined;\n\n if (action === 'thumbnail') {\n const stream = await itemProvider.getThumbnail(drive, itemAccountId);\n res.setHeader('Content-Type', 'image/webp');\n if (config.cors?.enabled) {\n res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');\n }\n stream.pipe(res);\n return true;\n }\n\n const { stream, mime, size: fileSize } = await itemProvider.openStream(drive, itemAccountId);\n const safeFilename = sanitizeContentDispositionFilename(drive.name);\n\n const format = req.query.format as string;\n const quality = req.query.quality as string;\n const display = req.query.display as string;\n const sizePreset = req.query.size as string;\n const fit = req.query.fit as string;\n const position = req.query.position as string;\n\n const isImage = mime.startsWith('image/');\n const shouldTransform = isImage && (format || quality || display || sizePreset || fit);\n\n res.setHeader('Content-Disposition', `inline; filename=\"${safeFilename}\"`);\n\n if (config.cors?.enabled) {\n res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');\n }\n\n if (shouldTransform) {\n try {\n const settings = getImageSettings(fileSize, quality, display, sizePreset, fit, position);\n\n let targetFormat = format || mime.split('/')[1];\n if (targetFormat === 'jpg') targetFormat = 'jpeg';\n if (!['jpeg', 'png', 'webp', 'avif'].includes(targetFormat)) {\n targetFormat = format || 'webp';\n }\n\n const cacheDir = path.join(config.storage.path, 'file', drive._id.toString(), 'cache');\n const cacheKey = [\n 'opt',\n `q${settings.quality}`,\n `e${settings.effort}`,\n settings.width ? `${settings.width}x${settings.height}` : 'orig',\n settings.fit || 'none',\n settings.position || 'c',\n targetFormat,\n ].join('_');\n const cachePath = path.join(cacheDir, `${cacheKey}.bin`);\n\n if (fs.existsSync(cachePath)) {\n const cacheStat = fs.statSync(cachePath);\n res.setHeader('Content-Type', `image/${targetFormat}`);\n res.setHeader('Content-Length', cacheStat.size);\n res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');\n if (config.cors?.enabled) {\n res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');\n }\n if ('destroy' in stream) {\n (stream as NodeJS.ReadableStream & { destroy: () => void }).destroy();\n }\n fs.createReadStream(cachePath).pipe(res);\n return true;\n }\n\n if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });\n\n let pipeline = sharp();\n\n if (settings.width && settings.height) {\n pipeline = pipeline.resize(settings.width, settings.height, {\n fit: settings.fit || 'inside',\n position: settings.position || 'center',\n withoutEnlargement: true,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n });\n }\n\n if (targetFormat === 'jpeg') {\n pipeline = pipeline.jpeg({ quality: settings.quality, mozjpeg: true });\n res.setHeader('Content-Type', 'image/jpeg');\n } else if (targetFormat === 'png') {\n pipeline = pipeline.png({ compressionLevel: settings.pngCompression, adaptiveFiltering: true });\n res.setHeader('Content-Type', 'image/png');\n } else if (targetFormat === 'webp') {\n const webpEffort = Math.min(settings.effort, 6);\n pipeline = pipeline.webp({ quality: settings.quality, effort: webpEffort });\n res.setHeader('Content-Type', 'image/webp');\n } else if (targetFormat === 'avif') {\n pipeline = pipeline.avif({ quality: settings.quality, effort: settings.effort });\n res.setHeader('Content-Type', 'image/avif');\n }\n\n res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');\n\n pipeline.on('error', (err) => {\n console.error('[next-drive] Pipeline error:', err);\n });\n\n stream.pipe(pipeline);\n\n pipeline.clone().toFile(cachePath).catch(e => console.error('[next-drive] Cache write failed:', e));\n pipeline.clone().pipe(res);\n return true;\n } catch (e) {\n console.error('[next-drive] Image transformation failed:', e);\n }\n }\n\n res.setHeader('Content-Type', mime);\n if (fileSize) res.setHeader('Content-Length', fileSize);\n stream.pipe(res);\n return true;\n } catch (error) {\n console.error(`[next-drive] Error in ${action}:`, error);\n const detail = error instanceof Error ? error.message : 'Something went wrong while serving the file';\n res.status(500).json({ status: 500, message: `Request \"${action}\" failed: ${detail}` });\n return true;\n }\n};\n","import type { NextApiRequest, NextApiResponse } from 'next';\nimport { google } from 'googleapis';\nimport { getDriveConfig } from '@/server/config';\nimport StorageAccount from '@/server/database/mongoose/schema/storage/account';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport { GoogleDriveProvider } from '@/server/storage-adapters/google';\n\nexport const handleAuthAction = async (\n req: NextApiRequest,\n res: NextApiResponse,\n action: string,\n config: ReturnType<typeof getDriveConfig>,\n owner: Record<string, unknown> | null\n): Promise<boolean> => {\n if (!['getAuthUrl', 'callback', 'listAccounts', 'removeAccount'].includes(action)) {\n return false;\n }\n\n switch (action) {\n case 'getAuthUrl': {\n const { provider } = req.query;\n if (provider === 'GOOGLE') {\n const { clientId, clientSecret, redirectUri } = config.storage?.google || {};\n if (!clientId || !clientSecret || !redirectUri) {\n res.status(500).json({ status: 500, message: 'Google Drive is not configured on the server' });\n return true;\n }\n\n const callbackUri = new URL(redirectUri);\n callbackUri.searchParams.set('action', 'callback');\n const oAuth2Client = new google.auth.OAuth2(clientId, clientSecret, callbackUri.toString());\n const state = Buffer.from(JSON.stringify({ owner })).toString('base64');\n const url = oAuth2Client.generateAuthUrl({\n access_type: 'offline',\n scope: ['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/userinfo.email'],\n state,\n prompt: 'consent',\n });\n res.status(200).json({ status: 200, message: 'Auth URL generated', data: { url } });\n return true;\n }\n res.status(400).json({ status: 400, message: 'Unknown storage provider requested' });\n return true;\n }\n\n case 'callback': {\n const { code } = req.query;\n if (!code) {\n res.status(400).json({ status: 400, message: 'Google sign-in failed: authorization code missing' });\n return true;\n }\n\n const { clientId, clientSecret, redirectUri } = config.storage?.google || {};\n if (!clientId || !clientSecret || !redirectUri) {\n res.status(500).json({ status: 500, message: 'Google Drive sign-in is not configured on the server' });\n return true;\n }\n\n const callbackUri = new URL(redirectUri);\n callbackUri.searchParams.set('action', 'callback');\n const oAuth2Client = new google.auth.OAuth2(clientId, clientSecret, callbackUri.toString());\n\n const { tokens } = await oAuth2Client.getToken(code as string);\n oAuth2Client.setCredentials(tokens);\n\n const oauth2 = google.oauth2({ version: 'v2', auth: oAuth2Client });\n const userInfo = await oauth2.userinfo.get();\n\n const existing = await StorageAccount.findOne({ owner, 'metadata.google.email': userInfo.data.email, 'metadata.provider': 'GOOGLE' });\n if (existing) {\n existing.metadata.google.credentials = tokens as Record<string, unknown>;\n existing.markModified('metadata');\n await existing.save();\n } else {\n const newAccount = new StorageAccount({\n owner,\n name: userInfo.data.name || 'Google Drive',\n metadata: {\n provider: 'GOOGLE',\n google: {\n email: userInfo.data.email,\n credentials: tokens as Record<string, unknown>,\n },\n },\n });\n await newAccount.save();\n }\n\n res.setHeader('Content-Type', 'text/html');\n res.send(`<!DOCTYPE html>\n<html>\n<head><title>Authentication Complete</title></head>\n<body>\n<p>Authentication successful! This window will close automatically.</p>\n<script>\n(function() {\n\\tif (window.opener) {\n\\t\\ttry {\n\\t\\t\\twindow.opener.postMessage('oauth-success', '*');\n\\t\\t} catch (e) {}\n\\t}\n\\ttry {\n\\t\\tlocalStorage.setItem('next-drive-oauth-success', Date.now().toString());\n\\t\\tlocalStorage.removeItem('next-drive-oauth-success');\n\\t} catch (e) {}\n\\twindow.close();\n\\tsetTimeout(function() {\n\\t\\tdocument.body.innerHTML = '<p style=\"font-family: system-ui; text-align: center; margin-top: 50px;\">Authentication successful!<br>You can close this tab now.</p>';\n\\t}, 500);\n})();\n</script>\n</body>\n</html>`);\n return true;\n }\n\n case 'listAccounts': {\n const accounts = await StorageAccount.find({ owner });\n res.status(200).json({\n status: 200,\n data: {\n accounts: accounts.map(a => ({\n id: a._id.toString(),\n name: a.name,\n email: a.metadata.google?.email || '',\n provider: a.metadata.provider,\n })),\n },\n });\n return true;\n }\n\n case 'removeAccount': {\n const { id } = req.query;\n const account = await StorageAccount.findOne({ _id: id, owner });\n if (!account) {\n res.status(404).json({ status: 404, message: 'Could not disconnect: account not found' });\n return true;\n }\n\n if (account.metadata.provider === 'GOOGLE') {\n try {\n await GoogleDriveProvider.revokeToken(owner, account._id.toString());\n } catch (e) {\n console.error('Failed to revoke Google token:', e);\n }\n }\n\n await StorageAccount.deleteOne({ _id: id, owner });\n await Drive.deleteMany({ owner, storageAccountId: id });\n res.status(200).json({ status: 200, message: 'Account removed' });\n return true;\n }\n\n default:\n return false;\n }\n};\n","import { z } from 'zod';\r\nimport { isValidObjectId } from 'mongoose';\r\n\r\n// ** Custom ObjectId validator\r\nconst objectIdSchema = z.string().refine(val => isValidObjectId(val), {\r\n message: 'Invalid ObjectId format',\r\n});\r\n\r\n// ** Sanitize filename - remove path traversal and dangerous characters\r\nconst sanitizeFilename = (name: string): string => {\r\n return (\r\n name\r\n .replace(/[<>:\"|?*\\x00-\\x1F]/g, '') // Remove dangerous chars\r\n .replace(/^\\.+/, '') // Remove leading dots\r\n .replace(/\\.+$/, '') // Remove trailing dots\r\n .replace(/\\\\/g, '/') // Normalize slashes\r\n .replace(/\\/+/g, '/') // Remove duplicate slashes\r\n .replace(/\\.\\.\\//g, '') // Remove path traversal\r\n .replace(/\\.\\.+/g, '') // Remove remaining ..\r\n .split('/')\r\n .pop() ||\r\n '' // Take only the filename part (remove all paths)\r\n .trim()\r\n .slice(0, 255)\r\n ); // Limit length\r\n};\r\n\r\n// ** Sanitize search query for regex\r\nconst sanitizeRegexInput = (input: string): string => {\r\n // Escape regex special characters\r\n return input.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&').slice(0, 100);\r\n};\r\n\r\n// ** File/Folder name schema\r\nconst nameSchema = z\r\n .string()\r\n .min(1, 'Name is required')\r\n .max(255, 'Name too long')\r\n .transform(sanitizeFilename)\r\n .refine(val => val.length > 0, { message: 'Invalid name after sanitization' });\r\n\r\n// ** Upload chunk schema\r\nexport const uploadChunkSchema = z\r\n .object({\r\n chunkIndex: z.number().int().min(0).max(10000),\r\n totalChunks: z.number().int().min(1).max(10000),\r\n driveId: z.string().optional(),\r\n fileName: nameSchema,\r\n fileSize: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),\r\n fileType: z.string().min(1).max(255),\r\n folderId: z.string().optional(),\r\n unauthenticated: z.coerce.boolean().optional(),\r\n })\r\n .refine(data => data.chunkIndex < data.totalChunks, {\r\n message: 'Chunk index must be less than total chunks',\r\n });\r\n\r\n// ** List query schema\r\nexport const listQuerySchema = z.object({\r\n folderId: z.union([z.literal('root'), objectIdSchema, z.undefined()]),\r\n limit: z\r\n .string()\r\n .optional()\r\n .transform(val => {\r\n const num = parseInt(val || '50', 10);\r\n return Math.min(Math.max(1, num), 100);\r\n }),\r\n afterId: objectIdSchema.optional(),\r\n});\r\n\r\n// ** Serve query schema\r\nexport const serveQuerySchema = z.object({\r\n id: objectIdSchema,\r\n token: z.string().optional(),\r\n});\r\n\r\n// ** Thumbnail query schema\r\nexport const thumbnailQuerySchema = z.object({\r\n id: objectIdSchema,\r\n size: z.enum(['small', 'medium', 'large']).optional().default('medium'),\r\n token: z.string().optional(),\r\n});\r\n\r\n// ** Rename body schema\r\nexport const renameBodySchema = z.object({\r\n id: objectIdSchema,\r\n newName: nameSchema,\r\n});\r\n\r\n// ** Delete query schema\r\nexport const deleteQuerySchema = z.object({\r\n id: objectIdSchema,\r\n});\r\n\r\n// ** Delete many body schema\r\nexport const deleteManyBodySchema = z.object({\r\n ids: z.array(objectIdSchema).min(1).max(1000),\r\n});\r\n\r\n// ** Create folder body schema\r\nexport const createFolderBodySchema = z.object({\r\n name: nameSchema,\r\n parentId: z.union([z.literal('root'), objectIdSchema, z.string().length(0), z.undefined()]).optional(),\r\n});\r\n\r\n// ** Move body schema\r\nexport const moveBodySchema = z.object({\r\n ids: z.array(objectIdSchema).min(1).max(1000),\r\n targetFolderId: z.union([z.literal('root'), objectIdSchema, z.undefined()]).optional(),\r\n});\r\n\r\n// ** Reorder body schema\r\nexport const reorderBodySchema = z.object({\r\n ids: z.array(objectIdSchema).min(1).max(1000),\r\n});\r\n\r\n// ** Search query schema\r\nexport const searchQuerySchema = z.object({\r\n q: z.string().min(1).max(100).transform(sanitizeRegexInput),\r\n folderId: z.union([z.literal('root'), objectIdSchema, z.undefined()]).optional(),\r\n limit: z\r\n .string()\r\n .optional()\r\n .transform(val => {\r\n const num = parseInt(val || '50', 10);\r\n return Math.min(Math.max(1, num), 100);\r\n }),\r\n trashed: z\r\n .string()\r\n .optional()\r\n .transform(val => val === 'true'),\r\n});\r\n\r\n// ** Restore query schema\r\nexport const restoreQuerySchema = z.object({\r\n id: objectIdSchema,\r\n});\r\n\r\n// ** Cancel query schema (accepts UUID since uploads use crypto.randomUUID())\r\nexport const cancelQuerySchema = z.object({\r\n id: z.string().uuid(),\r\n});\r\n\r\n// ** Purge trash query schema\r\nexport const purgeTrashQuerySchema = z.object({\r\n days: z.number().int().min(1).max(365).optional(),\r\n});\r\n\r\n// ** Drive File Schema (Public)\r\nexport const driveFileSchemaZod = z.object({\r\n id: z.string(),\r\n file: z.object({\r\n name: z.string(),\r\n mime: z.string(),\r\n size: z.number(),\r\n }),\r\n});\r\n\r\n// ** Constants\r\nexport const MAX_FOLDER_DEPTH = 50;\r\n\r\n// ** Export sanitization functions\r\nexport { sanitizeFilename, sanitizeRegexInput };\r\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport crypto from 'crypto';\nimport type { Readable } from 'stream';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport { getDriveConfig, getDriveInformation } from '@/server/config';\nimport { computeFileHash, extractImageMetadata, validateMimeType } from '@/server/utils';\nimport type { IDatabaseDriveDocument } from '@/server/database/mongoose/schema/drive';\nimport type { TDatabaseDrive } from '@/types/lib/database/drive';\nimport type { TDriveFile } from '@/types/client';\nimport { LocalStorageProvider } from '@/server/storage-adapters/local';\nimport { GoogleDriveProvider } from '@/server/storage-adapters/google';\n\nexport const getNextOrderValue = async (owner: Record<string, unknown> | null): Promise<number> => {\n const lastItem = await Drive.findOne({ owner }, {}, { sort: { order: -1 } });\n return lastItem ? lastItem.order + 1 : 0;\n};\n\nexport const getStorageUsed = async (owner: Record<string, unknown> | null): Promise<number> => {\n try {\n const result = await Drive.aggregate([{ $match: { owner, 'information.type': 'FILE', trashedAt: null } }, { $group: { _id: null, total: { $sum: '$information.sizeInBytes' } } }]);\n return result[0]?.total || 0;\n } catch {\n return 0;\n }\n};\n\nexport const getAllFolderContents = async (folderId: string, owner: Record<string, unknown> | null, maxDepth = 50, currentDepth = 0): Promise<IDatabaseDriveDocument[]> => {\n if (currentDepth >= maxDepth) throw new Error('This folder is nested too deeply to read all of its contents');\n\n const items = await Drive.find({ parentId: folderId, owner }).exec();\n const result: IDatabaseDriveDocument[] = [...items];\n\n for (const item of items) {\n if (item.information.type === 'FOLDER') {\n const subItems = await getAllFolderContents(String(item._id), owner, maxDepth, currentDepth + 1);\n result.push(...subItems);\n }\n }\n return result;\n};\n\nexport const driveGetUrl = (fileId: string, options?: { expiry?: number | Date }): string => {\n const config = getDriveConfig();\n if (!config.security?.signedUrls?.enabled) {\n return `/api/drive?action=serve&id=${fileId}`;\n }\n\n const { secret, expiresIn } = config.security.signedUrls;\n let expiryTimestamp: number;\n\n if (options?.expiry instanceof Date) {\n expiryTimestamp = Math.floor(options.expiry.getTime() / 1000);\n } else if (typeof options?.expiry === 'number') {\n expiryTimestamp = Math.floor(Date.now() / 1000) + options.expiry;\n } else {\n expiryTimestamp = Math.floor(Date.now() / 1000) + expiresIn;\n }\n\n const signature = crypto.createHmac('sha256', secret).update(`${fileId}:${expiryTimestamp}`).digest('hex');\n const token = Buffer.from(`${expiryTimestamp}:${signature}`).toString('base64url');\n return `${config.apiUrl || '/api/drive'}?action=serve&id=${fileId}&token=${token}`;\n};\n\nexport const driveAddSignedUrlToken = (item: TDatabaseDrive, config: ReturnType<typeof getDriveConfig>): TDatabaseDrive => {\n let token: string | undefined;\n\n if (config.security?.signedUrls?.enabled && config.security.signedUrls.secret) {\n const { secret, expiresIn } = config.security.signedUrls;\n const expiryTimestamp = Math.floor(Date.now() / 1000) + expiresIn;\n const signature = crypto.createHmac('sha256', secret).update(`${item.id}:${expiryTimestamp}`).digest('hex');\n token = Buffer.from(`${expiryTimestamp}:${signature}`).toString('base64url');\n }\n\n const apiUrl = config.apiUrl || '/api/drive';\n const url = `${apiUrl}?action=serve&id=${item.id}${token ? `&token=${token}` : ''}`;\n\n return { ...item, token, url };\n};\n\nexport const driveAddSignedUrlTokens = (items: TDatabaseDrive[], config: ReturnType<typeof getDriveConfig>): TDatabaseDrive[] => {\n return items.map(item => driveAddSignedUrlToken(item, config));\n};\n\n/**\n * Read a file and return a readable stream.\n * @param file - Either a file ID (string) or a TDatabaseDrive/IDatabaseDriveDocument object\n * @returns Promise with readable stream, mime type, and file size\n * @example\n * ```typescript\n * // Using file ID\n * const { stream, mime, size } = await driveReadFile('694f5013226de007be94fcc0');\n * stream.pipe(response);\n * \n * // Using database document\n * const drive = await Drive.findById(fileId);\n * const { stream, mime, size } = await driveReadFile(drive);\n * ```\n */\nexport const driveReadFile = async (\n file: string | IDatabaseDriveDocument | TDatabaseDrive\n): Promise<{ stream: Readable; mime: string; size: number }> => {\n let drive: IDatabaseDriveDocument;\n\n // If file is a string (ID), fetch from database\n if (typeof file === 'string') {\n const doc = await Drive.findById(file);\n if (!doc) throw new Error('Could not read file: the file no longer exists');\n drive = doc;\n } else if ('toClient' in file) {\n // Already an IDatabaseDriveDocument (Mongoose document)\n drive = file;\n } else {\n throw new Error('Could not read file: invalid file reference provided');\n }\n\n if (drive.information.type !== 'FILE') {\n throw new Error('Could not read file: this item is a folder, not a file');\n }\n\n // Determine provider based on drive's provider type\n const provider = drive.provider?.type === 'GOOGLE' ? GoogleDriveProvider : LocalStorageProvider;\n const accountId = drive.storageAccountId?.toString();\n\n // Use provider's openStream method\n return await provider.openStream(drive, accountId);\n};\n\n/**\n * Get detailed information about a file or folder\n * @param source - Either a file/folder ID (string) or a TDriveFile object\n * @returns Promise with detailed file/folder information\n * @example\n * ```typescript\n * // Using file ID\n * const info = await driveInfo('694f5013226de007be94fcc0');\n * console.log(info.name, info.size, info.createdAt);\n * \n * // Using TDriveFile\n * const file = { id: '123', file: { name: 'photo.jpg', mime: 'image/jpeg', size: 1024 } };\n * const info = await driveInfo(file);\n * ```\n */\nexport const driveInfo = async (\n source: string | TDriveFile\n): Promise<import('@/types/client').TDriveInformation> => {\n const fileId = typeof source === 'string' ? source : source.id;\n\n const drive = await Drive.findById(fileId);\n if (!drive) throw new Error('Could not load file details: the file no longer exists');\n\n // Get parent folder name if exists\n let parentName: string | undefined;\n if (drive.parentId) {\n const parent = await Drive.findById(drive.parentId);\n if (parent) parentName = parent.name;\n }\n\n // Build the response\n const info: import('@/types/client').TDriveInformation = {\n id: String(drive._id),\n name: drive.name,\n type: drive.information.type,\n status: drive.status,\n provider: drive.provider,\n parent: {\n id: drive.parentId ? String(drive.parentId) : null,\n name: parentName,\n },\n createdAt: drive.createdAt,\n trashedAt: drive.trashedAt,\n };\n\n // Add file-specific information\n if (drive.information.type === 'FILE') {\n info.mime = drive.information.mime;\n info.size = drive.information.sizeInBytes;\n info.hash = drive.information.hash;\n\n // Add image dimensions if available\n if (drive.information.width && drive.information.height) {\n info.dimensions = {\n width: drive.information.width,\n height: drive.information.height,\n };\n }\n\n // Add video duration if available\n if (drive.information.duration) {\n info.duration = drive.information.duration;\n }\n }\n\n return info;\n};\n\n/**\n * Get the local file system path for a file. For Google Drive files, downloads them to a local cache first.\n * @param file - Either a file ID (string) or a TDatabaseDrive/IDatabaseDriveDocument object\n * @returns Promise with readonly object containing the absolute file path and metadata\n * @example\n * ```typescript\n * // Using file ID\n * const { path, mime, size } = await driveFilePath('694f5013226de007be94fcc0');\n * const data = fs.readFileSync(path);\n * \n * // Using database document\n * const drive = await Drive.findById(fileId);\n * const { path, name, provider } = await driveFilePath(drive);\n * await processFile(path);\n * ```\n */\nexport const driveFilePath = async (\n file: string | IDatabaseDriveDocument | TDatabaseDrive\n): Promise<Readonly<{ path: string; name: string; mime: string; size: number; provider: string }>> => {\n let drive: IDatabaseDriveDocument;\n\n // If file is a string (ID), fetch from database\n if (typeof file === 'string') {\n const doc = await Drive.findById(file);\n if (!doc) throw new Error('Could not locate file: the file no longer exists');\n drive = doc;\n } else if ('toClient' in file) {\n // Already an IDatabaseDriveDocument (Mongoose document)\n drive = file;\n } else {\n throw new Error('Could not locate file: invalid file reference provided');\n }\n\n if (drive.information.type !== 'FILE') {\n throw new Error('Could not locate file: this item is a folder, not a file');\n }\n\n const config = getDriveConfig();\n const STORAGE_PATH = config.storage.path;\n const providerType = drive.provider?.type || 'LOCAL';\n\n // For LOCAL files, return the existing path directly\n if (providerType === 'LOCAL') {\n const filePath = path.join(STORAGE_PATH, 'file', String(drive._id), 'data.bin');\n\n if (!fs.existsSync(filePath)) {\n throw new Error('Could not locate file: the stored file is missing from disk');\n }\n\n return Object.freeze({\n path: filePath,\n name: drive.name,\n mime: drive.information.mime,\n size: drive.information.sizeInBytes,\n provider: 'LOCAL'\n });\n }\n\n // For GOOGLE files, download to file directory\n if (providerType === 'GOOGLE') {\n const fileDir = path.join(STORAGE_PATH, 'file', String(drive._id));\n const cachedFilePath = path.join(fileDir, 'data.bin');\n\n // Check if already cached\n if (fs.existsSync(cachedFilePath)) {\n const stats = fs.statSync(cachedFilePath);\n\n // Verify cached file size matches (simple integrity check)\n if (stats.size === drive.information.sizeInBytes) {\n return Object.freeze({\n path: cachedFilePath,\n name: drive.name,\n mime: drive.information.mime,\n size: drive.information.sizeInBytes,\n provider: 'GOOGLE'\n });\n }\n\n // Size mismatch, re-download\n fs.unlinkSync(cachedFilePath);\n }\n\n // Download from Google Drive\n const accountId = drive.storageAccountId?.toString();\n const { stream } = await GoogleDriveProvider.openStream(drive, accountId);\n\n // Create file directory if it doesn't exist\n if (!fs.existsSync(fileDir)) {\n fs.mkdirSync(fileDir, { recursive: true });\n }\n\n // Download to temp file first, then move (atomic operation)\n const tempPath = `${cachedFilePath}.tmp`;\n const writeStream = fs.createWriteStream(tempPath);\n\n await new Promise<void>((resolve, reject) => {\n stream.pipe(writeStream);\n writeStream.on('finish', resolve);\n writeStream.on('error', reject);\n stream.on('error', reject);\n });\n\n // Move temp file to final path - handle cross-device case\n try {\n fs.renameSync(tempPath, cachedFilePath);\n } catch (err: unknown) {\n if (err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'EXDEV') {\n fs.copyFileSync(tempPath, cachedFilePath);\n fs.unlinkSync(tempPath);\n } else {\n throw err;\n }\n }\n\n return Object.freeze({\n path: cachedFilePath,\n name: drive.name,\n mime: drive.information.mime,\n size: drive.information.sizeInBytes,\n provider: 'GOOGLE'\n });\n }\n\n throw new Error(`Could not locate file: unsupported storage provider \"${providerType}\"`);\n};\n\n/**\n * List files and folders in a specific directory.\n * @param options - List options including owner key, folderId, limit, and afterId for pagination\n * @returns Promise with array of drive items\n * @example\n * ```typescript\n * // List root folder\n * const items = await driveList({ key: { userId: '123' } });\n * \n * // List specific folder with limit\n * const items = await driveList({\n * key: { userId: '123' },\n * folderId: 'folderIdHere',\n * limit: 50\n * });\n * \n * // Pagination\n * const items = await driveList({\n * key: { userId: '123' },\n * folderId: 'root',\n * limit: 20,\n * afterId: 'lastItemId'\n * });\n * ```\n */\nexport const driveList = async (\n options: {\n key: Record<string, unknown> | null;\n folderId?: string | null;\n accountId?: string;\n limit?: number;\n afterId?: string;\n }\n): Promise<TDatabaseDrive[]> => {\n const { key, folderId, accountId, limit = 100, afterId } = options;\n\n // Determine provider\n let providerName: 'LOCAL' | 'GOOGLE' = 'LOCAL';\n if (accountId && accountId !== 'LOCAL') {\n const account = await Drive.db.model('StorageAccount').findOne({ _id: accountId, owner: key });\n if (!account) {\n throw new Error('Could not list files: storage account not found or access denied');\n }\n if (account.metadata.provider === 'GOOGLE') {\n providerName = 'GOOGLE';\n }\n }\n\n // Build query\n const query: Record<string, unknown> = {\n owner: key,\n 'provider.type': providerName,\n storageAccountId: accountId || null,\n parentId: folderId === 'root' || !folderId ? null : folderId,\n trashedAt: null,\n };\n\n if (afterId) {\n query._id = { $lt: afterId };\n }\n\n const items = await Drive.find(query, {}, { sort: { order: 1, _id: -1 }, limit });\n const config = getDriveConfig();\n return driveAddSignedUrlTokens(await Promise.all(items.map(item => item.toClient())), config);\n};\n\n/**\n * List files (not folders) with offset-based pagination.\n * @param options - List options including optional owner key, folderId, page, and limit\n * @returns Promise with paginated file items and pagination metadata\n * @example\n * ```typescript\n * // List all files (page 1, default limit 50)\n * const result = await driveListFiles({});\n *\n * // List files for a specific owner\n * const result = await driveListFiles({ key: { userId: '123' } });\n *\n * // List files in a folder with pagination\n * const result = await driveListFiles({\n * key: { userId: '123' },\n * folderId: 'folderIdHere',\n * page: 2,\n * limit: 20,\n * });\n *\n * // Access pagination info\n * console.log(result.pagination);\n * // { page: 2, limit: 20, totalCount: 87, totalPages: 5, hasMore: true }\n * ```\n */\nexport const driveListFiles = async (\n options: {\n key?: Record<string, unknown> | null;\n folderId?: string | null;\n accountId?: string;\n page?: number;\n limit?: number;\n }\n): Promise<{\n items: TDatabaseDrive[];\n pagination: {\n page: number;\n limit: number;\n totalCount: number;\n totalPages: number;\n hasMore: boolean;\n };\n}> => {\n const { key, folderId, accountId } = options;\n const page = Math.max(1, options.page ?? 1);\n const limit = Math.min(Math.max(1, options.limit ?? 50), 100);\n\n // Determine provider\n let providerName: 'LOCAL' | 'GOOGLE' = 'LOCAL';\n if (accountId && accountId !== 'LOCAL') {\n const account = await Drive.db.model('StorageAccount').findOne({ _id: accountId, owner: key });\n if (!account) {\n throw new Error('Could not load files: storage account not found or access denied');\n }\n if (account.metadata.provider === 'GOOGLE') {\n providerName = 'GOOGLE';\n }\n }\n\n // Build query — files only, not trashed\n const query: Record<string, unknown> = {\n 'provider.type': providerName,\n 'information.type': 'FILE',\n storageAccountId: accountId || null,\n trashedAt: null,\n };\n\n // Filter by owner when key is provided\n if (key !== undefined) {\n query.owner = key;\n }\n\n // Filter by folder\n if (folderId && folderId !== 'root') {\n query.parentId = folderId;\n } else if (folderId === 'root' || folderId === null) {\n query.parentId = null;\n }\n // When folderId is undefined, list files from all folders\n\n const skip = (page - 1) * limit;\n\n const [totalCount, items] = await Promise.all([\n Drive.countDocuments(query),\n Drive.find(query, {}, { sort: { createdAt: -1 }, skip, limit }),\n ]);\n\n const totalPages = Math.ceil(totalCount / limit);\n\n const config = getDriveConfig();\n\n return {\n items: driveAddSignedUrlTokens(await Promise.all(items.map(item => item.toClient())), config),\n pagination: {\n page,\n limit,\n totalCount,\n totalPages,\n hasMore: page < totalPages,\n },\n };\n};\n\n/**\n * Delete a file or folder permanently from the drive system.\n * @param source - File ID (string) or a TDatabaseDrive/IDatabaseDriveDocument object\n * @param options - Delete options including recurse flag\n * @returns Promise that resolves when deletion is complete\n * @example\n * ```typescript\n * // Delete a file\n * await driveDelete('694f5013226de007be94fcc0');\n * \n * // Delete a folder recursively (default behavior)\n * await driveDelete(folderId, { recurse: true });\n * \n * // Delete only if folder is empty\n * await driveDelete(folderId, { recurse: false }); // Throws error if folder has children\n * \n * // Delete using database document\n * const drive = await Drive.findById(fileId);\n * await driveDelete(drive);\n * ```\n */\nexport const driveDelete = async (\n source: string | IDatabaseDriveDocument | TDatabaseDrive,\n options?: { recurse?: boolean }\n): Promise<void> => {\n const { recurse = true } = options || {};\n\n let drive: IDatabaseDriveDocument;\n let driveId: string;\n\n // If source is a string (ID), fetch from database\n if (typeof source === 'string') {\n const doc = await Drive.findById(source);\n if (!doc) throw new Error('Could not delete: the file no longer exists');\n drive = doc;\n driveId = source;\n } else if ('toClient' in source) {\n // Already an IDatabaseDriveDocument (Mongoose document)\n drive = source;\n driveId = String(drive._id);\n } else {\n // TDatabaseDrive object (plain object from API)\n const doc = await Drive.findById(source.id);\n if (!doc) throw new Error('Could not delete: the selected file no longer exists');\n drive = doc;\n driveId = source.id;\n }\n\n // If it's a folder and recurse is false, check for children\n if (drive.information.type === 'FOLDER' && !recurse) {\n const owner = drive.owner as Record<string, unknown> | null;\n const childCount = await Drive.countDocuments({\n owner,\n parentId: driveId,\n trashedAt: null,\n });\n\n if (childCount > 0) {\n throw new Error(`Could not delete folder: it still contains ${childCount} item(s). Enable recursive delete to remove the folder and everything inside it.`);\n }\n }\n\n // Determine provider based on drive's provider type\n const provider = drive.provider?.type === 'GOOGLE' ? GoogleDriveProvider : LocalStorageProvider;\n const accountId = drive.storageAccountId?.toString();\n const owner = drive.owner as Record<string, unknown> | null;\n\n // Use provider's delete method to permanently delete the file/folder\n // Note: The provider's delete method already handles recursive deletion\n await provider.delete([driveId], owner, accountId);\n};\n\n/**\n * Resolve a folder path to a folder ID, creating folders recursively if they don't exist.\n * @param folderPath - Path like 'images/2024/january' or '/images/2024'\n * @param owner - Owner key for the folders\n * @param accountId - Storage account ID\n * @returns Promise with the resolved folder ID\n * @example\n * ```typescript\n * const folderId = await resolveFolderByPath('assets/images/avatars', { userId: '123' });\n * ```\n */\nexport const resolveFolderByPath = async (\n folderPath: string,\n owner: Record<string, unknown> | null,\n accountId?: string\n): Promise<string> => {\n // Normalize path: remove leading/trailing slashes, split by /\n const normalizedPath = folderPath.replace(/^\\/+|\\/+$/g, '');\n if (!normalizedPath) {\n throw new Error('Could not resolve folder: the folder path is empty');\n }\n\n const segments = normalizedPath.split('/').filter(s => s.length > 0);\n if (segments.length === 0) {\n throw new Error('Could not resolve folder: the folder path is invalid');\n }\n\n // Determine provider\n let providerName: 'LOCAL' | 'GOOGLE' = 'LOCAL';\n if (accountId && accountId !== 'LOCAL') {\n const account = await Drive.db.model('StorageAccount').findOne({ _id: accountId, owner });\n if (!account) {\n throw new Error('Could not resolve folder: storage account not found or access denied');\n }\n if (account.metadata.provider === 'GOOGLE') {\n providerName = 'GOOGLE';\n }\n }\n\n let currentParentId: string | null = null;\n\n // Traverse/create each segment of the path\n for (const segmentName of segments) {\n // Look for existing folder with this name under current parent\n const existingFolder: IDatabaseDriveDocument | null = await Drive.findOne({\n owner,\n 'provider.type': providerName,\n storageAccountId: accountId || null,\n parentId: currentParentId,\n name: segmentName,\n 'information.type': 'FOLDER',\n trashedAt: null,\n });\n\n if (existingFolder) {\n // Folder exists, move to next level\n currentParentId = String(existingFolder._id);\n } else {\n // Create the folder\n const provider = providerName === 'GOOGLE' ? GoogleDriveProvider : LocalStorageProvider;\n const newFolder = await provider.createFolder(segmentName, currentParentId, owner, accountId);\n currentParentId = newFolder.id;\n }\n }\n\n return currentParentId!;\n};\n\n/**\n * Upload a file to the drive system from a file path or readable stream.\n * @param source - File path (string) or Readable stream\n * @param key - Owner key (must match the authenticated user's key)\n * @param options - Upload options including name, folder (id or path), accountId, mime, and enforce flag\n * @returns Promise with the created drive file object\n * @example\n * ```typescript\n * // Upload to specific folder by ID\n * const file = await driveUpload('/tmp/photo.jpg', { userId: '123' }, {\n * name: 'photo.jpg',\n * folder: { id: 'folderId' },\n * enforce: false\n * });\n * \n * // Upload to folder by path (creates folders if not exist)\n * const file = await driveUpload('/tmp/photo.jpg', { userId: '123' }, {\n * name: 'photo.jpg',\n * folder: { path: 'images/2024/january' }\n * });\n * \n * // Upload from stream with custom MIME type\n * const stream = fs.createReadStream('/tmp/video.mp4');\n * const file = await driveUpload(stream, { userId: '123' }, {\n * name: 'video.mp4',\n * mime: 'video/mp4',\n * enforce: true // Skip quota check\n * });\n * \n * // Upload from Buffer with MIME type\n * const buffer = Buffer.from('data');\n * const file = await driveUpload(buffer, { userId: '123' }, {\n * name: 'data.bin',\n * mime: 'application/octet-stream'\n * });\n * ```\n */\nexport const driveUpload = async (\n source: string | Readable | Buffer,\n key: Record<string, unknown> | null,\n options: {\n name: string;\n folder?: { id: string } | { path: string };\n /** @deprecated Use folder.id instead */\n parentId?: string | null;\n accountId?: string;\n mime?: string;\n enforce?: boolean;\n meta?: Record<string, unknown>;\n }\n): Promise<TDriveFile> => {\n const config = getDriveConfig();\n\n // Determine provider based on accountId\n let provider: typeof LocalStorageProvider | typeof GoogleDriveProvider = LocalStorageProvider;\n const accountId: string | undefined = options.accountId;\n\n if (accountId && accountId !== 'LOCAL') {\n // Validate account belongs to owner\n const account = await Drive.db.model('StorageAccount').findOne({ _id: accountId, owner: key });\n if (!account) {\n throw new Error('Could not upload: storage account not found or access denied');\n }\n if (account.metadata.provider === 'GOOGLE') {\n provider = GoogleDriveProvider;\n }\n }\n\n // Create temporary file if source is a stream or buffer\n let tempFilePath: string | null = null;\n let sourceFilePath: string;\n let fileSize: number;\n\n if (typeof source === 'string') {\n // Source is a file path\n if (!fs.existsSync(source)) {\n throw new Error('Could not upload: source file not found');\n }\n sourceFilePath = source;\n const stats = fs.statSync(source);\n fileSize = stats.size;\n } else if (Buffer.isBuffer(source)) {\n // Source is a Buffer\n const tempDir = path.join(os.tmpdir(), 'next-drive-uploads');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n\n tempFilePath = path.join(tempDir, `upload-${crypto.randomUUID()}.tmp`);\n fs.writeFileSync(tempFilePath, source);\n\n sourceFilePath = tempFilePath;\n fileSize = source.length;\n } else {\n // Source is a Readable stream\n const tempDir = path.join(os.tmpdir(), 'next-drive-uploads');\n if (!fs.existsSync(tempDir)) {\n fs.mkdirSync(tempDir, { recursive: true });\n }\n\n tempFilePath = path.join(tempDir, `upload-${crypto.randomUUID()}.tmp`);\n const writeStream = fs.createWriteStream(tempFilePath);\n\n await new Promise<void>((resolve, reject) => {\n source.pipe(writeStream);\n writeStream.on('finish', resolve);\n writeStream.on('error', reject);\n source.on('error', reject);\n });\n\n sourceFilePath = tempFilePath;\n const stats = fs.statSync(tempFilePath);\n fileSize = stats.size;\n }\n\n try {\n // Detect MIME type from options or file extension\n let mimeType: string;\n\n if (options.mime) {\n // Use provided MIME type\n mimeType = options.mime;\n } else {\n // Auto-detect from file extension\n const ext = path.extname(options.name).toLowerCase();\n const mimeTypes: Record<string, string> = {\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.png': 'image/png',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n '.mp4': 'video/mp4',\n '.mov': 'video/quicktime',\n '.avi': 'video/x-msvideo',\n '.pdf': 'application/pdf',\n '.doc': 'application/msword',\n '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n '.xls': 'application/vnd.ms-excel',\n '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n '.txt': 'text/plain',\n '.json': 'application/json',\n '.zip': 'application/zip',\n };\n mimeType = mimeTypes[ext] || 'application/octet-stream';\n }\n\n // Validate MIME type only if security config exists\n if (config.security && !validateMimeType(mimeType, config.security.allowedMimeTypes)) {\n throw new Error(`Could not upload: file type \"${mimeType}\" is not allowed`);\n }\n\n // Validate file size only if security config exists\n if (config.security && fileSize > config.security.maxUploadSizeInBytes) {\n throw new Error('Could not upload: file is larger than the maximum allowed size');\n }\n\n // Quota Check (skip in ROOT mode or if enforce is true)\n const isRootMode = config.mode === 'ROOT';\n if (!options.enforce && !isRootMode) {\n const information = await getDriveInformation({ method: 'KEY', key });\n const quota = await provider.getQuota(key, accountId, information.storage.quotaInBytes);\n if (quota.usedInBytes + fileSize > quota.quotaInBytes) {\n throw new Error('Could not upload: you have run out of storage space');\n }\n }\n\n // Resolve folder ID from folder.path, folder.id, or legacy parentId\n let resolvedParentId: string | null = null;\n\n if (options.folder && 'path' in options.folder) {\n // Create folders recursively if needed\n resolvedParentId = await resolveFolderByPath(options.folder.path, key, accountId);\n } else if (options.folder && 'id' in options.folder && options.folder.id !== 'root') {\n resolvedParentId = options.folder.id;\n } else if (options.parentId && options.parentId !== 'root') {\n // Legacy support\n resolvedParentId = options.parentId;\n }\n\n // Create Drive Document\n const drive = new Drive({\n owner: key,\n storageAccountId: accountId || null,\n provider: { type: provider.name },\n name: options.name,\n parentId: resolvedParentId,\n order: await getNextOrderValue(key),\n information: { type: 'FILE', sizeInBytes: fileSize, mime: mimeType, path: '' },\n status: 'UPLOADING',\n meta: options.meta || {},\n });\n\n // Set initial path for LOCAL provider\n if (provider.name === 'LOCAL' && drive.information.type === 'FILE') {\n drive.information.path = path.join('file', String(drive._id), 'data.bin');\n }\n\n await drive.save();\n\n // Upload file through provider\n try {\n const item = await provider.uploadFile(drive, sourceFilePath, accountId);\n // Return simplified TDriveFile format for public API\n return {\n id: item.id,\n file: {\n name: item.name,\n mime: item.information.type === 'FILE' ? item.information.mime : 'application/x-folder',\n size: item.information.type === 'FILE' ? item.information.sizeInBytes : 0,\n },\n };\n } catch (err) {\n // Upload failed, cleanup DB record\n await Drive.deleteOne({ _id: drive._id });\n throw err;\n }\n } finally {\n // Cleanup temporary file if created from stream\n if (tempFilePath && fs.existsSync(tempFilePath)) {\n fs.rmSync(tempFilePath, { force: true });\n }\n }\n};\n\n/**\n * Clean up orphaned file folders from storage that are no longer registered in the database.\n * Scans the `{storage.path}/file/` directory, checks each folder ID against the Drive collection,\n * and removes folders that have no matching database record.\n * @returns Promise with list of removed folder IDs and total freed bytes\n * @example\n * ```typescript\n * const result = await driveCleanup();\n * console.log(`Removed ${result.removed.length} orphaned folders`);\n * console.log(`Freed ${result.totalFreedInBytes} bytes`);\n * ```\n */\nexport const driveCleanup = async (): Promise<{\n removed: string[];\n totalFreedInBytes: number;\n}> => {\n const config = getDriveConfig();\n const fileDir = path.join(config.storage.path, 'file');\n\n // If file directory doesn't exist, nothing to clean\n if (!fs.existsSync(fileDir)) {\n return { removed: [], totalFreedInBytes: 0 };\n }\n\n // Read all subdirectory names (each is a Mongo ObjectId)\n const folderNames = fs.readdirSync(fileDir).filter(name => {\n const fullPath = path.join(fileDir, name);\n return fs.statSync(fullPath).isDirectory();\n });\n\n if (folderNames.length === 0) {\n return { removed: [], totalFreedInBytes: 0 };\n }\n\n // Get directory size recursively\n const getDirSize = (dirPath: string): number => {\n let size = 0;\n try {\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n for (const entry of entries) {\n const entryPath = path.join(dirPath, entry.name);\n if (entry.isFile()) {\n size += fs.statSync(entryPath).size;\n } else if (entry.isDirectory()) {\n size += getDirSize(entryPath);\n }\n }\n } catch { /* ignore read errors */ }\n return size;\n };\n\n // Batch query the database (process in chunks of 500)\n const BATCH_SIZE = 500;\n const existingIds = new Set<string>();\n\n for (let i = 0; i < folderNames.length; i += BATCH_SIZE) {\n const batch = folderNames.slice(i, i + BATCH_SIZE);\n const docs = await Drive.find(\n { _id: { $in: batch } },\n { _id: 1 }\n ).lean();\n for (const doc of docs) {\n existingIds.add(doc._id.toString());\n }\n }\n\n // Remove orphaned folders\n const removed: string[] = [];\n let totalFreedInBytes = 0;\n\n for (const name of folderNames) {\n if (!existingIds.has(name)) {\n const dirPath = path.join(fileDir, name);\n try {\n totalFreedInBytes += getDirSize(dirPath);\n fs.rmSync(dirPath, { recursive: true, force: true });\n removed.push(name);\n } catch (e) {\n console.error(`[next-drive] Failed to remove orphaned folder ${name}:`, e);\n }\n }\n }\n\n // Clean up temp directory if it exists inside storage path\n const tempDir = path.join(config.storage.path, 'temp');\n if (fs.existsSync(tempDir)) {\n try {\n totalFreedInBytes += getDirSize(tempDir);\n fs.rmSync(tempDir, { recursive: true, force: true });\n } catch (e) {\n console.error('[next-drive] Failed to remove temp directory:', e);\n }\n }\n\n // Clean up leftover upload chunks from system temp directory\n const systemTmpDir = path.join(os.tmpdir(), 'next-drive-uploads');\n if (fs.existsSync(systemTmpDir)) {\n try {\n totalFreedInBytes += getDirSize(systemTmpDir);\n fs.rmSync(systemTmpDir, { recursive: true, force: true });\n } catch (e) {\n console.error('[next-drive] Failed to remove system temp directory:', e);\n }\n }\n\n return { removed, totalFreedInBytes };\n};\n\n/**\n * Confirm an upload so it is kept permanently. Clears the `expiresAt` field so a temporary\n * (anonymous) upload is no longer auto-deleted. Safe to call on already-permanent files\n * (e.g. uploaded while logged in) \\u2014 it is a no-op for them.\n * @param id - Drive file id\n * @returns Promise<boolean> - true if the file exists\n * @example\n * ```typescript\n * await driveConfirm(driveFile.id);\n * ```\n */\nexport const driveConfirm = async (id: string): Promise<boolean> => {\n const result = await Drive.updateOne({ _id: id }, { $set: { expiresAt: null } });\n return result.matchedCount > 0;\n};\n\n/**\n * Permanently delete all unconfirmed temporary uploads whose `expiresAt` has passed.\n * Intended to be run on a schedule (e.g. cron/interval) by the consuming application.\n * @returns Promise with list of removed ids and total freed bytes\n * @example\n * ```typescript\n * const result = await drivePurgeExpired();\n * console.log(`Purged ${result.removed.length} expired files`);\n * ```\n */\nexport const drivePurgeExpired = async (): Promise<{\n removed: string[];\n totalFreedInBytes: number;\n}> => {\n const expired = await Drive.find({ expiresAt: { $ne: null, $lt: new Date() } });\n const removed: string[] = [];\n let totalFreedInBytes = 0;\n\n for (const drive of expired) {\n const id = String(drive._id);\n try {\n await driveDelete(drive);\n totalFreedInBytes += drive.information.type === 'FILE' ? drive.information.sizeInBytes : 0;\n removed.push(id);\n } catch (e) {\n console.error(`[next-drive] Failed to purge expired file ${id}:`, e);\n }\n }\n\n return { removed, totalFreedInBytes };\n};","import type { NextApiRequest } from 'next';\nimport { getDriveConfig } from '@/server/config';\nimport Drive from '@/server/database/mongoose/schema/drive';\nimport { driveAddSignedUrlToken, driveAddSignedUrlTokens } from '@/server/controllers/drive';\nimport StorageAccount from '@/server/database/mongoose/schema/storage/account';\nimport { LocalStorageProvider } from '@/server/storage-adapters/local';\nimport { GoogleDriveProvider } from '@/server/storage-adapters/google';\nimport type { TDatabaseDrive } from '@/types/server';\nimport type { TStorageProvider } from '@/types/server/storage';\n\nexport type TProviderResolution = {\n provider: TStorageProvider;\n accountId?: string;\n};\n\nexport const resolveProvider = async (req: NextApiRequest, owner: Record<string, unknown> | null): Promise<TProviderResolution> => {\n const accountId = req.headers['x-drive-account'] as string;\n\n if (!accountId || accountId === 'LOCAL') {\n return { provider: LocalStorageProvider };\n }\n\n const account = await StorageAccount.findOne({ _id: accountId, owner });\n if (!account) {\n throw new Error('Storage account not found or access denied');\n }\n\n if (account.metadata.provider === 'GOOGLE') {\n return { provider: GoogleDriveProvider, accountId: account._id.toString() };\n }\n\n return { provider: LocalStorageProvider };\n};\n\nexport const withSignedUrl = (item: TDatabaseDrive, config: ReturnType<typeof getDriveConfig>): TDatabaseDrive => {\n return driveAddSignedUrlToken(item, config);\n};\n\nexport const withSignedUrls = (items: TDatabaseDrive[], config: ReturnType<typeof getDriveConfig>): TDatabaseDrive[] => {\n return driveAddSignedUrlTokens(items, config);\n};\n\nexport { Drive };\n","import type { NextApiRequest, NextApiResponse } from 'next';\nimport formidable from 'formidable';\nimport path from 'path';\nimport fs from 'fs';\nimport os from 'os';\nimport crypto from 'crypto';\nimport { getDriveConfig } from '@/server/config';\nimport * as schemas from '@/server/zod/schemas';\nimport { validateMimeType } from '@/server/utils';\nimport type { TDatabaseDrive, TDriveConfigInformation } from '@/types/server';\nimport type { TStorageProvider } from '@/types/server/storage';\nimport { GoogleDriveProvider } from '@/server/storage-adapters/google';\nimport { LocalStorageProvider } from '@/server/storage-adapters/local';\nimport { withSignedUrl, withSignedUrls, Drive } from '@/server/actions/shared';\nimport { resolveProvider } from '@/server/actions/shared';\n\ntype TDriveActionContext = {\n req: NextApiRequest;\n res: NextApiResponse;\n action: string;\n config: ReturnType<typeof getDriveConfig>;\n owner: Record<string, unknown> | null;\n isRootMode: boolean;\n information: TDriveConfigInformation;\n provider: TStorageProvider;\n accountId?: string;\n};\n\nexport const handleDriveAction = async (ctx: TDriveActionContext): Promise<void> => {\n const { req, res, action, config, owner, isRootMode, information, provider, accountId } = ctx;\n\n switch (action) {\n case 'list': {\n if (req.method !== 'GET') return void res.status(405).json({ status: 405, message: 'Listing files requires a GET request' });\n const listQuery = schemas.listQuerySchema.safeParse(req.query);\n if (!listQuery.success) return void res.status(400).json({ status: 400, message: 'Could not list files: invalid request parameters' });\n\n const { folderId, limit, afterId } = listQuery.data;\n\n try {\n await provider.sync(folderId || 'root', owner, accountId);\n } catch (e) {\n console.error('Sync failed', e);\n }\n\n const query: Record<string, unknown> = {\n 'provider.type': provider.name,\n storageAccountId: accountId || null,\n parentId: folderId === 'root' || !folderId ? null : folderId,\n trashedAt: null,\n };\n\n if (!isRootMode) {\n query.owner = owner;\n }\n\n if (afterId) query._id = { $lt: afterId };\n\n const items = await Drive.find(query, {}, { sort: { order: 1, _id: -1 }, limit });\n const plainItems = withSignedUrls(await Promise.all(items.map(item => item.toClient())), config);\n\n res.status(200).json({ status: 200, message: 'Items retrieved', data: { items: plainItems, hasMore: items.length === limit } });\n return;\n }\n\n case 'search': {\n const searchData = schemas.searchQuerySchema.safeParse(req.query);\n if (!searchData.success) return void res.status(400).json({ status: 400, message: 'Could not search: invalid request parameters' });\n const { q, folderId, limit, trashed } = searchData.data;\n\n if (!trashed) {\n try {\n await provider.search(q, owner, accountId);\n } catch (e) {\n console.error('Search sync failed', e);\n }\n }\n\n const query: Record<string, unknown> = {\n 'provider.type': provider.name,\n storageAccountId: accountId || null,\n trashedAt: trashed ? { $ne: null } : null,\n name: { $regex: q, $options: 'i' },\n };\n\n if (!isRootMode) {\n query.owner = owner;\n }\n\n if (folderId && folderId !== 'root') query.parentId = folderId;\n\n const items = await Drive.find(query, {}, { limit, sort: { createdAt: -1 } });\n const plainItems = withSignedUrls(await Promise.all(items.map(i => i.toClient())), config);\n\n res.status(200).json({ status: 200, message: 'Results', data: { items: plainItems } });\n return;\n }\n\n case 'upload': {\n if (req.method !== 'POST') return void res.status(405).json({ status: 405, message: 'Uploading requires a POST request' });\n const systemTmpDir = path.join(os.tmpdir(), 'next-drive-uploads');\n if (!fs.existsSync(systemTmpDir)) fs.mkdirSync(systemTmpDir, { recursive: true });\n const form = formidable({\n multiples: false,\n maxFileSize: (config.security?.maxUploadSizeInBytes ?? 1024 * 1024 * 1024) * 2,\n uploadDir: systemTmpDir,\n keepExtensions: true,\n });\n\n const [fields, files] = await new Promise<[formidable.Fields, formidable.Files]>((resolve, reject) => {\n form.parse(req, (err, parsedFields, parsedFiles) => {\n if (err) reject(err);\n else resolve([parsedFields, parsedFiles]);\n });\n });\n\n const cleanupTempFiles = (allFiles: formidable.Files) => {\n Object.values(allFiles)\n .flat()\n .forEach(file => {\n if (file && fs.existsSync(file.filepath)) fs.rmSync(file.filepath, { force: true });\n });\n };\n\n const getString = (f: string[] | string | undefined) => (Array.isArray(f) ? f[0] : f || '');\n const getInt = (f: string[] | string | undefined) => parseInt(getString(f) || '0', 10);\n\n const uploadData = schemas.uploadChunkSchema.safeParse({\n chunkIndex: getInt(fields.chunkIndex),\n totalChunks: getInt(fields.totalChunks),\n driveId: getString(fields.driveId) || undefined,\n fileName: getString(fields.fileName),\n fileSize: getInt(fields.fileSize),\n fileType: getString(fields.fileType),\n folderId: getString(fields.folderId) || undefined,\n });\n\n if (!uploadData.success) {\n cleanupTempFiles(files);\n return void res.status(400).json({ status: 400, message: uploadData.error.errors[0].message });\n }\n\n const { chunkIndex, totalChunks, driveId, fileName, fileSize: fileSizeInBytes, fileType, folderId, unauthenticated } = uploadData.data;\n let currentUploadId = driveId;\n const tempBaseDir = path.join(os.tmpdir(), 'next-drive-uploads');\n\n if (!currentUploadId) {\n if (chunkIndex !== 0) return void res.status(400).json({ message: 'Could not upload: missing upload session for this chunk' });\n\n if (unauthenticated) {\n const unauth = config.security?.unauthenticated;\n if (!unauth?.enabled) {\n cleanupTempFiles(files);\n return void res.status(403).json({ status: 403, message: 'Anonymous uploads are not enabled' });\n }\n if (fileSizeInBytes > unauth.maxUploadSizeInBytes) {\n cleanupTempFiles(files);\n return void res.status(413).json({ status: 413, message: 'Could not upload: file exceeds the maximum allowed size' });\n }\n if (fileType && !validateMimeType(fileType, unauth.allowedMimeTypes)) {\n cleanupTempFiles(files);\n return void res.status(400).json({ status: 400, message: `Could not upload: file type \"${fileType}\" is not allowed` });\n }\n\n const abuse = unauth.abuse;\n if (abuse) {\n const store = (globalThis as any).__nextDrive.abuse as { ipHits: Map<string, number[]>; concurrent: number };\n const now = Date.now();\n const ip =\n abuse.clientId?.(req) ??\n ((abuse.trustedHeaders ?? ['cf-connecting-ip', 'x-forwarded-for']).map(h => req.headers[h]).find(Boolean) as string | undefined)?.split(',')[0].trim() ??\n req.socket.remoteAddress ??\n 'unknown';\n const hits = (store.ipHits.get(ip) ?? []).filter(t => now - t < 3600000);\n\n const perIp = abuse.perIp;\n if (perIp && hits.filter(t => now - t < perIp.windowMinutes * 60000).length >= perIp.max) {\n cleanupTempFiles(files);\n return void res.status(429).json({ status: 429, message: 'Too many uploads, please try again later' });\n }\n if (abuse.hourlyPerIp && hits.length >= abuse.hourlyPerIp) {\n cleanupTempFiles(files);\n return void res.status(429).json({ status: 429, message: 'Hourly upload limit reached, please try again later' });\n }\n if (abuse.maxConcurrent && store.concurrent >= abuse.maxConcurrent) {\n cleanupTempFiles(files);\n return void res.status(429).json({ status: 429, message: 'Server is busy with uploads, please try again later' });\n }\n if (abuse.maxLiveBytes) {\n const [agg] = await Drive.aggregate([{ $match: { expiresAt: { $ne: null } } }, { $group: { _id: null, total: { $sum: '$information.sizeInBytes' } } }]);\n if ((agg?.total ?? 0) + fileSizeInBytes > abuse.maxLiveBytes) {\n cleanupTempFiles(files);\n return void res.status(429).json({ status: 429, message: 'Temporary storage is full, please try again later' });\n }\n }\n\n hits.push(now);\n store.ipHits.set(ip, hits);\n store.concurrent++;\n }\n } else {\n if (fileType && config.security) {\n if (!validateMimeType(fileType, config.security.allowedMimeTypes)) {\n cleanupTempFiles(files);\n return void res.status(400).json({ status: 400, message: `Could not upload: file type \"${fileType}\" is not allowed` });\n }\n }\n\n if (!isRootMode) {\n const quota = await provider.getQuota(owner, accountId, information.storage.quotaInBytes);\n if (quota.usedInBytes + fileSizeInBytes > quota.quotaInBytes) {\n cleanupTempFiles(files);\n return void res.status(413).json({ status: 413, message: 'Could not upload: you have run out of storage space' });\n }\n }\n }\n\n currentUploadId = crypto.randomUUID();\n const uploadDir = path.join(tempBaseDir, currentUploadId);\n fs.mkdirSync(uploadDir, { recursive: true });\n\n const metadata = {\n owner: unauthenticated ? null : owner,\n accountId: unauthenticated ? null : accountId,\n providerName: provider.name,\n name: fileName,\n parentId: unauthenticated || folderId === 'root' || !folderId ? null : folderId,\n fileSize: fileSizeInBytes,\n mimeType: fileType,\n totalChunks,\n unauthenticated: !!unauthenticated,\n };\n fs.writeFileSync(path.join(uploadDir, 'metadata.json'), JSON.stringify(metadata));\n }\n\n if (!currentUploadId) {\n cleanupTempFiles(files);\n return void res.status(400).json({ status: 400, message: 'Could not upload: invalid upload request' });\n }\n\n const uploadDir = path.join(tempBaseDir, currentUploadId);\n if (!fs.existsSync(uploadDir)) {\n cleanupTempFiles(files);\n return void res.status(404).json({ status: 404, message: 'Could not upload: this upload session was not found or has expired' });\n }\n\n try {\n const chunkFile = Array.isArray(files.chunk) ? files.chunk[0] : files.chunk;\n if (!chunkFile) throw new Error('Could not upload: no file chunk was received');\n\n const partPath = path.join(uploadDir, `part_${chunkIndex}`);\n\n try {\n fs.renameSync(chunkFile.filepath, partPath);\n } catch (err: unknown) {\n if (err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code === 'EXDEV') {\n fs.copyFileSync(chunkFile.filepath, partPath);\n fs.unlinkSync(chunkFile.filepath);\n } else {\n throw err;\n }\n }\n\n const uploadedParts = fs.readdirSync(uploadDir).filter(f => f.startsWith('part_'));\n if (uploadedParts.length === totalChunks) {\n const metaPath = path.join(uploadDir, 'metadata.json');\n const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'));\n\n const finalTempPath = path.join(uploadDir, 'final.bin');\n const writeStream = fs.createWriteStream(finalTempPath);\n let streamError: Error | null = null;\n writeStream.on('error', (err) => {\n streamError = err;\n });\n\n await new Promise<void>((resolve, reject) => {\n writeStream.on('open', () => resolve());\n writeStream.once('error', reject);\n });\n\n for (let i = 0; i < totalChunks; i++) {\n if (streamError) {\n writeStream.destroy();\n throw streamError;\n }\n const pPath = path.join(uploadDir, `part_${i}`);\n if (!fs.existsSync(pPath)) {\n writeStream.destroy();\n throw new Error(`Could not finish upload: chunk ${i} is missing`);\n }\n const data = fs.readFileSync(pPath);\n const canContinue = writeStream.write(data);\n\n if (!canContinue) {\n await new Promise<void>((resolve, reject) => {\n writeStream.once('drain', resolve);\n writeStream.once('error', reject);\n });\n }\n }\n\n await new Promise<void>((resolve, reject) => {\n if (streamError) {\n reject(streamError);\n return;\n }\n writeStream.end();\n writeStream.on('finish', resolve);\n writeStream.once('error', reject);\n });\n\n if (!fs.existsSync(finalTempPath)) {\n throw new Error('Could not finish upload: failed to assemble the file');\n }\n\n const finalStats = fs.statSync(finalTempPath);\n if (finalStats.size !== meta.fileSize) {\n throw new Error('Could not finish upload: the assembled file is incomplete (size mismatch)');\n }\n\n const drive = new Drive({\n owner: meta.owner,\n storageAccountId: meta.accountId || null,\n provider: { type: meta.providerName },\n name: meta.name,\n parentId: meta.parentId,\n order: 0,\n information: { type: 'FILE', sizeInBytes: meta.fileSize, mime: meta.mimeType, path: '' },\n status: 'UPLOADING',\n currentChunk: totalChunks,\n totalChunks,\n expiresAt: meta.unauthenticated ? new Date(Date.now() + (config.security?.unauthenticated?.ttlMinutes ?? 60) * 60000) : null,\n });\n\n if (meta.providerName === 'LOCAL' && drive.information.type === 'FILE') {\n drive.information.path = path.join('file', String(drive._id), 'data.bin');\n }\n\n await drive.save();\n\n try {\n const item = await provider.uploadFile(drive, finalTempPath, meta.accountId);\n fs.rmSync(uploadDir, { recursive: true, force: true });\n if (meta.unauthenticated) (globalThis as any).__nextDrive.abuse.concurrent = Math.max(0, (globalThis as any).__nextDrive.abuse.concurrent - 1);\n\n const newQuota = await provider.getQuota(meta.owner, meta.accountId, information.storage.quotaInBytes);\n res.status(200).json({ status: 200, message: 'Upload complete', data: { type: 'UPLOAD_COMPLETE', driveId: String(drive._id), item: withSignedUrl(item, config) }, statistic: { storage: newQuota } });\n } catch (err) {\n await Drive.deleteOne({ _id: drive._id });\n if (meta.unauthenticated) (globalThis as any).__nextDrive.abuse.concurrent = Math.max(0, (globalThis as any).__nextDrive.abuse.concurrent - 1);\n throw err;\n }\n } else {\n const newQuota = await provider.getQuota(owner, accountId, information.storage.quotaInBytes);\n if (chunkIndex === 0) {\n res.status(200).json({ status: 200, message: 'Upload started', data: { type: 'UPLOAD_STARTED', driveId: currentUploadId }, statistic: { storage: newQuota } });\n } else {\n res.status(200).json({ status: 200, message: 'Chunk received', data: { type: 'CHUNK_RECEIVED', driveId: currentUploadId, chunkIndex }, statistic: { storage: newQuota } });\n }\n }\n } catch (e) {\n cleanupTempFiles(files);\n throw e;\n }\n return;\n }\n\n case 'cancel': {\n const cancelData = schemas.cancelQuerySchema.safeParse(req.query);\n if (!cancelData.success) return void res.status(400).json({ status: 400, message: 'Could not cancel upload: invalid ID' });\n const { id } = cancelData.data;\n\n const tempUploadDir = path.join(os.tmpdir(), 'next-drive-uploads', id);\n if (fs.existsSync(tempUploadDir)) {\n try {\n const metaPath = path.join(tempUploadDir, 'metadata.json');\n if (fs.existsSync(metaPath) && JSON.parse(fs.readFileSync(metaPath, 'utf-8')).unauthenticated) {\n (globalThis as any).__nextDrive.abuse.concurrent = Math.max(0, (globalThis as any).__nextDrive.abuse.concurrent - 1);\n }\n fs.rmSync(tempUploadDir, { recursive: true, force: true });\n } catch (e) {\n console.error('Failed to cleanup temp upload:', e);\n }\n }\n\n res.status(200).json({ status: 200, message: 'Upload cancelled', data: null });\n return;\n }\n\n case 'createFolder': {\n const folderData = schemas.createFolderBodySchema.safeParse(req.body);\n if (!folderData.success) return void res.status(400).json({ status: 400, message: folderData.error.errors[0].message });\n const { name, parentId } = folderData.data;\n\n const item = withSignedUrl(await provider.createFolder(name, parentId ?? null, owner, accountId), config);\n res.status(201).json({ status: 201, message: 'Folder created', data: { item } });\n return;\n }\n\n case 'delete': {\n const deleteData = schemas.deleteQuerySchema.safeParse(req.query);\n if (!deleteData.success) return void res.status(400).json({ status: 400, message: 'Could not move to trash: invalid ID' });\n const { id } = deleteData.data;\n const drive = await Drive.findById(id);\n if (!drive) return void res.status(404).json({ status: 404, message: 'Could not move to trash: item not found' });\n\n const itemProvider = drive.provider?.type === 'GOOGLE' ? GoogleDriveProvider : LocalStorageProvider;\n const itemAccountId = drive.storageAccountId ? drive.storageAccountId.toString() : undefined;\n\n try {\n await itemProvider.trash([id], owner, itemAccountId);\n } catch (e) {\n console.error('Provider trash failed:', e);\n }\n\n drive.trashedAt = new Date();\n await drive.save();\n res.status(200).json({ status: 200, message: 'Moved to trash', data: null });\n return;\n }\n\n case 'deletePermanent': {\n const deleteData = schemas.deleteQuerySchema.safeParse(req.query);\n if (!deleteData.success) return void res.status(400).json({ status: 400, message: 'Could not delete: invalid ID' });\n const { id } = deleteData.data;\n await provider.delete([id], owner, accountId);\n const quota = await provider.getQuota(owner, accountId, information.storage.quotaInBytes);\n res.status(200).json({ status: 200, message: 'Deleted', statistic: { storage: quota } });\n return;\n }\n\n case 'quota': {\n const quota = await provider.getQuota(owner, accountId, information.storage.quotaInBytes);\n res.status(200).json({\n status: 200,\n message: 'Quota retrieved',\n data: {\n usedInBytes: quota.usedInBytes,\n totalInBytes: quota.quotaInBytes,\n availableInBytes: Math.max(0, quota.quotaInBytes - quota.usedInBytes),\n percentage: quota.quotaInBytes > 0 ? Math.round((quota.usedInBytes / quota.quotaInBytes) * 100) : 0,\n },\n statistic: { storage: quota },\n });\n return;\n }\n\n case 'trash': {\n try {\n const { provider: trashProvider, accountId: trashAccountId } = await resolveProvider(req, owner);\n await trashProvider.syncTrash(owner, trashAccountId);\n } catch (e) {\n console.error('Trash sync failed', e);\n }\n\n const query: Record<string, unknown> = {\n owner,\n 'provider.type': provider.name,\n storageAccountId: accountId || null,\n trashedAt: { $ne: null },\n };\n\n const items = await Drive.find(query, {}, { sort: { trashedAt: -1 } });\n const plainItems = withSignedUrls(await Promise.all(items.map(item => item.toClient())), config);\n\n res.status(200).json({ status: 200, message: 'Trash items', data: { items: plainItems, hasMore: false } });\n return;\n }\n\n case 'restore': {\n const restoreData = schemas.deleteQuerySchema.safeParse(req.query);\n if (!restoreData.success) return void res.status(400).json({ status: 400, message: 'Could not restore: invalid ID' });\n const { id } = restoreData.data;\n const drive = await Drive.findById(id);\n if (!drive) return void res.status(404).json({ status: 404, message: 'Could not restore: item not found' });\n\n let targetParentId = drive.parentId;\n if (targetParentId) {\n const parent = await Drive.findById(targetParentId);\n if (parent?.trashedAt) {\n targetParentId = null;\n }\n }\n\n const itemProvider = drive.provider?.type === 'GOOGLE' ? GoogleDriveProvider : LocalStorageProvider;\n const itemAccountId = drive.storageAccountId ? drive.storageAccountId.toString() : undefined;\n\n try {\n await itemProvider.untrash([id], owner, itemAccountId);\n if (targetParentId !== drive.parentId) {\n await itemProvider.move(id, targetParentId?.toString() ?? null, owner, itemAccountId);\n }\n } catch (e) {\n console.error('Provider restore failed:', e);\n }\n\n drive.trashedAt = null;\n drive.parentId = targetParentId;\n await drive.save();\n\n res.status(200).json({\n status: 200,\n message: targetParentId === null && drive.parentId !== null ? 'Restored to root (parent folder was trashed)' : 'Restored',\n data: null,\n });\n return;\n }\n\n case 'move': {\n const moveData = schemas.moveBodySchema.safeParse(req.body);\n if (!moveData.success) return void res.status(400).json({ status: 400, message: 'Could not move: invalid request data' });\n const { ids, targetFolderId } = moveData.data;\n\n const items: TDatabaseDrive[] = [];\n const effectiveTargetId = targetFolderId === 'root' || !targetFolderId ? null : targetFolderId;\n\n for (const id of ids) {\n try {\n const item = await provider.move(id, effectiveTargetId, owner, accountId);\n items.push(item);\n } catch (e) {\n console.error(`Failed to move item ${id}`, e);\n }\n }\n\n res.status(200).json({ status: 200, message: 'Moved', data: { items: withSignedUrls(items, config) } });\n return;\n }\n\n case 'reorder': {\n if (req.method !== 'POST') {\n return void res.status(405).json({ status: 405, message: 'Reordering requires a POST request' });\n }\n\n const reorderData = schemas.reorderBodySchema.safeParse(req.body);\n if (!reorderData.success) {\n return void res.status(400).json({ status: 400, message: 'Could not reorder: invalid request data' });\n }\n\n const { ids } = reorderData.data;\n\n const query: Record<string, unknown> = {\n _id: { $in: ids },\n 'provider.type': provider.name,\n storageAccountId: accountId || null,\n trashedAt: null,\n };\n\n if (!isRootMode) {\n query.owner = owner;\n }\n\n const existingItems = await Drive.find(query, { _id: 1, parentId: 1 });\n if (existingItems.length !== ids.length) {\n return void res.status(404).json({ status: 404, message: 'Could not reorder: one or more items were not found' });\n }\n\n const parentIds = new Set(existingItems.map(item => (item.parentId ? item.parentId.toString() : 'root')));\n if (parentIds.size > 1) {\n return void res.status(400).json({ status: 400, message: 'Could not reorder: all items must be in the same folder' });\n }\n\n const operations = ids.map((id, order) => ({\n updateOne: {\n filter: {\n _id: id,\n 'provider.type': provider.name,\n storageAccountId: accountId || null,\n trashedAt: null,\n ...(isRootMode ? {} : { owner }),\n },\n update: { $set: { order } },\n },\n }));\n\n await Drive.bulkWrite(operations as never);\n\n const updatedItems = await Drive.find(query, {}, { sort: { order: 1 } });\n const plainItems = withSignedUrls(await Promise.all(updatedItems.map(item => item.toClient())), config);\n\n res.status(200).json({ status: 200, message: 'Reordered', data: { items: plainItems } });\n return;\n }\n\n case 'rename': {\n const renameData = schemas.renameBodySchema.safeParse({ id: req.query.id, ...req.body });\n if (!renameData.success) return void res.status(400).json({ status: 400, message: 'Could not rename: invalid request data' });\n const { id, newName } = renameData.data;\n const item = withSignedUrl(await provider.rename(id, newName, owner, accountId), config);\n res.status(200).json({ status: 200, message: 'Renamed', data: { item } });\n return;\n }\n\n default: {\n res.status(400).json({ status: 400, message: `Unknown action requested: \"${action}\"` });\n return;\n }\n }\n};\n","import type { NextApiRequest, NextApiResponse } from 'next';\n\nimport { getDriveConfig, getDriveInformation, driveConfiguration } from '@/server/config';\nimport { applyCorsHeaders } from '@/server/actions/cors';\nimport { handlePublicAction } from '@/server/actions/public';\nimport { handleAuthAction } from '@/server/actions/auth';\nimport { handleDriveAction } from '@/server/actions/drive';\nimport { resolveProvider } from '@/server/actions/shared';\n\n// ** Main API handler for all drive operations\nexport const driveAPIHandler = async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {\n const action = (req.query.action as string) || (req.query.code && req.query.state ? 'callback' : undefined);\n\n let config: ReturnType<typeof getDriveConfig>;\n try {\n config = getDriveConfig();\n } catch (error) {\n console.error('[next-drive] Configuration error:', error);\n res.status(500).json({ status: 500, message: 'Drive is not ready: failed to initialize configuration' });\n return;\n }\n\n const isPreflightHandled = applyCorsHeaders(req, res, config);\n if (isPreflightHandled) return;\n\n if (!action) {\n res.status(400).json({ status: 400, message: 'Missing \"action\" parameter in request' });\n return;\n }\n\n const wasPublicHandled = await handlePublicAction(req, res, action, config);\n if (wasPublicHandled) return;\n\n try {\n const mode = config.mode || 'NORMAL';\n\n if (action === 'information') {\n const { clientId, clientSecret, redirectUri } = config.storage?.google || {};\n const googleConfigured = !!(clientId && clientSecret && redirectUri);\n\n let authenticated = false;\n try {\n await getDriveInformation({ method: 'REQUEST', req });\n authenticated = true;\n } catch {\n authenticated = false;\n }\n\n res.status(200).json({\n status: 200,\n message: 'Information retrieved',\n data: {\n providers: {\n google: googleConfigured,\n },\n mode,\n authenticated,\n unauthenticatedUploads: !!config.security?.unauthenticated?.enabled,\n },\n });\n return;\n }\n\n const information = await getDriveInformation({ method: 'REQUEST', req });\n const { key: owner } = information;\n const isRootMode = mode === 'ROOT';\n\n const wasAuthHandled = await handleAuthAction(req, res, action, config, owner);\n if (wasAuthHandled) return;\n\n const { provider, accountId } = await resolveProvider(req, owner);\n\n await handleDriveAction({\n req,\n res,\n action,\n config,\n owner,\n isRootMode,\n information,\n provider,\n accountId,\n });\n } catch (error: unknown) {\n console.error(`[next-drive] Error handling action ${action}:`, error);\n const detail = error instanceof Error ? error.message : 'Something went wrong while processing your request';\n res.status(500).json({ status: 500, message: `Request \"${action}\" failed: ${detail}` });\n }\n};\n\nexport { driveConfiguration, getDriveConfig, getDriveInformation };\nexport { driveGetUrl, driveReadFile, driveFilePath, driveUpload, driveDelete, driveList, driveInfo, driveListFiles, driveCleanup, driveConfirm, drivePurgeExpired } from '@/server/controllers/drive';\nexport { default as DatabaseMongoDrive } from '@/server/database/mongoose/schema/drive';\nexport type { IDatabaseDriveDocument } from '@/server/database/mongoose/schema/drive';\nexport { driveFileSchemaZod } from '@/server/zod/schemas';\nexport { driveCreateUrl } from '@/client/utils';\nexport type { TDriveFile, TDriveInformation } from '@/types/client';\nexport type {\n TDriveDatabase,\n TDriveMode,\n TDriveInformationInput,\n TDriveConfigInformation,\n TDriveSecurityConfig,\n TDriveStorageConfig,\n TDriveCorsConfig,\n TDriveConfiguration,\n TDatabaseDriveStatus,\n TDatabaseDriveMetadataFile,\n TDatabaseDriveMetadataFolder,\n TDatabaseDriveInformation,\n TDatabaseDriveProvider,\n TDatabaseDriveMetadata,\n TDatabaseDrive,\n TDriveAction,\n TDriveAPIResponse,\n TDriveThumbnailSize,\n TDriveImageQuality,\n TMigration,\n TImageMetadata,\n TVideoMetadata,\n} from '@/types/server';\n"]}
|