Merge commit from fork

This commit is contained in:
dicedtomato
2026-05-20 08:54:59 -07:00
committed by GitHub
parent a8c65c19b4
commit 177febf305
3 changed files with 38 additions and 10 deletions
+15 -8
View File
@@ -3,6 +3,7 @@ import { access, constants, copyFile, readdir, rename, rm, stat, writeFile } fro
import { join, resolve, sep } from 'path';
import { Readable } from 'stream';
import { Datasource, ListOptions, PutOptions } from './Datasource';
import { log } from '../logger';
async function existsAndCanRW(path: string): Promise<boolean> {
try {
@@ -15,6 +16,7 @@ async function existsAndCanRW(path: string): Promise<boolean> {
export class LocalDatasource extends Datasource {
name = 'local';
logger = log('datasource').c('local');
constructor(public dir: string) {
super();
@@ -40,9 +42,7 @@ export class LocalDatasource extends Datasource {
public async put(file: string, data: Buffer | string, { noDelete }: PutOptions): Promise<void> {
const path = this.resolvePath(file);
if (!path) {
throw new Error('Invalid path provided');
}
if (!path) throw new Error('Invalid path provided');
// handles if given a path to a file, it will just move it instead of doing unecessary writes
if (typeof data === 'string' && data.startsWith('/')) {
@@ -69,14 +69,17 @@ export class LocalDatasource extends Datasource {
return;
}
const path = join(this.dir, file);
const path = this.resolvePath(file);
if (!path) throw new Error('Invalid path provided');
if (!existsSync(path)) return Promise.resolve();
return rm(path);
}
public async size(file: string): Promise<number> {
const path = join(this.dir, file);
const path = this.resolvePath(file);
if (!path) throw new Error('Invalid path provided');
if (!existsSync(path)) return 0;
const { size } = await stat(path);
@@ -98,15 +101,18 @@ export class LocalDatasource extends Datasource {
}
public async range(file: string, start: number, end: number): Promise<Readable> {
const path = join(this.dir, file);
const path = this.resolvePath(file);
if (!path) throw new Error('Invalid path provided');
const readStream = createReadStream(path, { start, end });
return readStream;
}
public async rename(from: string, to: string): Promise<void> {
const fromPath = join(this.dir, from);
const toPath = join(this.dir, to);
const fromPath = this.resolvePath(from);
const toPath = this.resolvePath(to);
if (!fromPath || !toPath) throw new Error('Invalid path provided');
if (!existsSync(fromPath))
throw new Error(`Something went very wrong! File ${from} does not exist in local datasource.`);
@@ -120,3 +126,4 @@ export class LocalDatasource extends Datasource {
return files.filter((f) => f.isFile() && f.name.startsWith(options.prefix || '')).map((f) => f.name);
}
}
+10 -1
View File
@@ -1,8 +1,10 @@
import { ApiError } from '@/lib/api/errors';
import { createToken } from '@/lib/crypto';
import { prisma } from '@/lib/db';
import { sanitizeFilename } from '@/lib/fs';
import { export3Schema } from '@/lib/import/version3/validateExport';
import { log } from '@/lib/logger';
import { randomCharacters } from '@/lib/random';
import { secondlyRatelimit } from '@/lib/ratelimits';
import { administratorMiddleware } from '@/server/middleware/administrator';
import { userMiddleware } from '@/server/middleware/user';
@@ -182,10 +184,16 @@ export default typedPlugin(
continue;
}
let sanitizedFilename = sanitizeFilename(file.name);
if (!sanitizedFilename) {
sanitizedFilename = randomCharacters(12);
logger.warn('file has invalid name, using random name', { file: id, new: sanitizedFilename });
}
const created = await prisma.file.create({
data: {
userId: user,
name: file.name,
name: sanitizedFilename,
originalName: file.original_name || null,
type: file.type,
size: file.size,
@@ -303,3 +311,4 @@ export default typedPlugin(
},
{ name: PATH },
);
+13 -1
View File
@@ -1,8 +1,10 @@
import { ApiError } from '@/lib/api/errors';
import { createToken } from '@/lib/crypto';
import { prisma } from '@/lib/db';
import { sanitizeFilename } from '@/lib/fs';
import { export4Schema } from '@/lib/import/version4/validateExport';
import { log } from '@/lib/logger';
import { randomCharacters } from '@/lib/random';
import { secondlyRatelimit } from '@/lib/ratelimits';
import { administratorMiddleware } from '@/server/middleware/administrator';
import { userMiddleware } from '@/server/middleware/user';
@@ -355,10 +357,19 @@ export default typedPlugin(
const folderId = file.folderId ? importedFolders[file.folderId] : null;
let sanitizedFilename = sanitizeFilename(file.name);
if (!sanitizedFilename) {
sanitizedFilename = randomCharacters(12);
logger.warn('file has invalid name, using random name', {
file: file.id,
new: sanitizedFilename,
});
}
const created = await prisma.file.create({
data: {
userId,
name: file.name,
name: sanitizedFilename,
size: file.size,
type: file.type,
folderId,
@@ -549,3 +560,4 @@ export default typedPlugin(
},
{ name: PATH },
);