summaryrefslogtreecommitdiff
path: root/packages/backend/src/services/drive/add-file.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src/services/drive/add-file.ts')
-rw-r--r--packages/backend/src/services/drive/add-file.ts80
1 files changed, 51 insertions, 29 deletions
diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts
index ee4d51a96d..a89e068f45 100644
--- a/packages/backend/src/services/drive/add-file.ts
+++ b/packages/backend/src/services/drive/add-file.ts
@@ -20,6 +20,7 @@ import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error';
import * as S3 from 'aws-sdk/clients/s3';
import { getS3 } from './s3';
import * as sharp from 'sharp';
+import { FILE_TYPE_BROWSERSAFE } from '@/const';
const logger = driveLogger.createSubLogger('register', 'yellow');
@@ -49,6 +50,12 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
if (type === 'image/vnd.mozilla.apng') ext = '.apng';
}
+ // 拡張子からContent-Typeを設定してそうな挙動を示すオブジェクトストレージ (upcloud?) も存在するので、
+ // 許可されているファイル形式でしか拡張子をつけない
+ if (!FILE_TYPE_BROWSERSAFE.includes(type)) {
+ ext = '';
+ }
+
const baseUrl = meta.objectStorageBaseUrl
|| `${ meta.objectStorageUseSSL ? 'https' : 'http' }://${ meta.objectStorageEndpoint }${ meta.objectStoragePort ? `:${meta.objectStoragePort}` : '' }/${ meta.objectStorageBucket }`;
@@ -94,13 +101,14 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
file.accessKey = key;
file.thumbnailAccessKey = thumbnailKey;
file.webpublicAccessKey = webpublicKey;
+ file.webpublicType = alts.webpublic?.type ?? null;
file.name = name;
file.type = type;
file.md5 = hash;
file.size = size;
file.storedInternal = false;
- return await DriveFiles.save(file);
+ return await DriveFiles.insert(file).then(x => DriveFiles.findOneOrFail(x.identifiers[0]));
} else { // use internal storage
const accessKey = uuid();
const thumbnailAccessKey = 'thumbnail-' + uuid();
@@ -128,12 +136,13 @@ async function save(file: DriveFile, path: string, name: string, type: string, h
file.accessKey = accessKey;
file.thumbnailAccessKey = thumbnailAccessKey;
file.webpublicAccessKey = webpublicAccessKey;
+ file.webpublicType = alts.webpublic?.type ?? null;
file.name = name;
file.type = type;
file.md5 = hash;
file.size = size;
- return await DriveFiles.save(file);
+ return await DriveFiles.insert(file).then(x => DriveFiles.findOneOrFail(x.identifiers[0]));
}
}
@@ -160,7 +169,7 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
}
}
- if (!['image/jpeg', 'image/png', 'image/webp'].includes(type)) {
+ if (!['image/jpeg', 'image/png', 'image/webp', 'image/svg+xml'].includes(type)) {
logger.debug(`web image and thumbnail not created (not an required file)`);
return {
webpublic: null,
@@ -201,7 +210,7 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
webpublic = await convertSharpToJpeg(img, 2048, 2048);
} else if (['image/webp'].includes(type)) {
webpublic = await convertSharpToWebp(img, 2048, 2048);
- } else if (['image/png'].includes(type)) {
+ } else if (['image/png', 'image/svg+xml'].includes(type)) {
webpublic = await convertSharpToPng(img, 2048, 2048);
} else {
logger.debug(`web image not created (not an required image)`);
@@ -220,7 +229,7 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
try {
if (['image/jpeg', 'image/webp'].includes(type)) {
thumbnail = await convertSharpToJpeg(img, 498, 280);
- } else if (['image/png'].includes(type)) {
+ } else if (['image/png', 'image/svg+xml'].includes(type)) {
thumbnail = await convertSharpToPngOrJpeg(img, 498, 280);
} else {
logger.debug(`thumbnail not created (not an required file)`);
@@ -241,6 +250,7 @@ export async function generateAlts(path: string, type: string, generateWeb: bool
*/
async function upload(key: string, stream: fs.ReadStream | Buffer, type: string, filename?: string) {
if (type === 'image/apng') type = 'image/png';
+ if (!FILE_TYPE_BROWSERSAFE.includes(type)) type = 'application/octet-stream';
const meta = await fetchMeta();
@@ -287,33 +297,45 @@ async function deleteOldFile(user: IRemoteUser) {
}
}
+type AddFileArgs = {
+ /** User who wish to add file */
+ user: { id: User['id']; host: User['host'] } | null;
+ /** File path */
+ path: string;
+ /** Name */
+ name?: string | null;
+ /** Comment */
+ comment?: string | null;
+ /** Folder ID */
+ folderId?: any;
+ /** If set to true, forcibly upload the file even if there is a file with the same hash. */
+ force?: boolean;
+ /** Do not save file to local */
+ isLink?: boolean;
+ /** URL of source (URLからアップロードされた場合(ローカル/リモート)の元URL) */
+ url?: string | null;
+ /** URL of source (リモートインスタンスのURLからアップロードされた場合の元URL) */
+ uri?: string | null;
+ /** Mark file as sensitive */
+ sensitive?: boolean | null;
+};
+
/**
* Add file to drive
*
- * @param user User who wish to add file
- * @param path File path
- * @param name Name
- * @param comment Comment
- * @param folderId Folder ID
- * @param force If set to true, forcibly upload the file even if there is a file with the same hash.
- * @param isLink Do not save file to local
- * @param url URL of source (URLからアップロードされた場合(ローカル/リモート)の元URL)
- * @param uri URL of source (リモートインスタンスのURLからアップロードされた場合の元URL)
- * @param sensitive Mark file as sensitive
- * @return Created drive file
*/
-export default async function(
- user: { id: User['id']; host: User['host'] } | null,
- path: string,
- name: string | null = null,
- comment: string | null = null,
- folderId: any = null,
- force: boolean = false,
- isLink: boolean = false,
- url: string | null = null,
- uri: string | null = null,
- sensitive: boolean | null = null
-): Promise<DriveFile> {
+export async function addFile({
+ user,
+ path,
+ name = null,
+ comment = null,
+ folderId = null,
+ force = false,
+ isLink = false,
+ url = null,
+ uri = null,
+ sensitive = null
+}: AddFileArgs): Promise<DriveFile> {
const info = await getFileInfo(path);
logger.info(`${JSON.stringify(info)}`);
@@ -428,7 +450,7 @@ export default async function(
file.type = info.type.mime;
file.storedInternal = false;
- file = await DriveFiles.save(file);
+ file = await DriveFiles.insert(file).then(x => DriveFiles.findOneOrFail(x.identifiers[0]));
} catch (e) {
// duplicate key error (when already registered)
if (isDuplicateKeyValueError(e)) {