diff options
author | Chocobozzz <me@florianbigard.com> | 2021-06-08 09:33:03 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-06-08 10:01:50 +0200 |
commit | ea54cd04c1ff0e55651cd5fb1a83672acde68604 (patch) | |
tree | 4e10fea658e72a9f79375d0e9b23d08915d3d0b2 | |
parent | 295106516277581ba4967199fa5580264a90ae2c (diff) | |
download | PeerTube-ea54cd04c1ff0e55651cd5fb1a83672acde68604.tar.gz PeerTube-ea54cd04c1ff0e55651cd5fb1a83672acde68604.tar.zst PeerTube-ea54cd04c1ff0e55651cd5fb1a83672acde68604.zip |
Fix video upload with a capitalized ext
-rw-r--r-- | server/controllers/api/videos/upload.ts | 4 | ||||
-rw-r--r-- | server/helpers/core-utils.ts | 88 | ||||
-rw-r--r-- | server/helpers/express-utils.ts | 4 | ||||
-rw-r--r-- | server/helpers/image-utils.ts | 7 | ||||
-rw-r--r-- | server/lib/activitypub/actors/shared/object-to-model-attributes.ts | 4 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-file-import.ts | 3 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 3 | ||||
-rw-r--r-- | server/lib/local-actor.ts | 5 | ||||
-rw-r--r-- | server/models/actor/actor.ts | 6 | ||||
-rw-r--r-- | shared/extra-utils/videos/videos.ts | 5 |
10 files changed, 81 insertions, 48 deletions
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index 783cc329a..e767492bc 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { move } from 'fs-extra' | 2 | import { move } from 'fs-extra' |
3 | import { extname } from 'path' | 3 | import { getLowercaseExtension } from '@server/helpers/core-utils' |
4 | import { deleteResumableUploadMetaFile, getResumableUploadPath } from '@server/helpers/upload' | 4 | import { deleteResumableUploadMetaFile, getResumableUploadPath } from '@server/helpers/upload' |
5 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 5 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
6 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' | 6 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' |
@@ -225,7 +225,7 @@ async function addVideo (options: { | |||
225 | 225 | ||
226 | async function buildNewFile (video: MVideo, videoPhysicalFile: express.VideoUploadFile) { | 226 | async function buildNewFile (video: MVideo, videoPhysicalFile: express.VideoUploadFile) { |
227 | const videoFile = new VideoFileModel({ | 227 | const videoFile = new VideoFileModel({ |
228 | extname: extname(videoPhysicalFile.filename), | 228 | extname: getLowercaseExtension(videoPhysicalFile.filename), |
229 | size: videoPhysicalFile.size, | 229 | size: videoPhysicalFile.size, |
230 | videoStreamingPlaylistId: null, | 230 | videoStreamingPlaylistId: null, |
231 | metadata: await getMetadataFromFile(videoPhysicalFile.path) | 231 | metadata: await getMetadataFromFile(videoPhysicalFile.path) |
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts index b93868c12..b5bf2c92c 100644 --- a/server/helpers/core-utils.ts +++ b/server/helpers/core-utils.ts | |||
@@ -8,7 +8,7 @@ | |||
8 | import { exec, ExecOptions } from 'child_process' | 8 | import { exec, ExecOptions } from 'child_process' |
9 | import { BinaryToTextEncoding, createHash, randomBytes } from 'crypto' | 9 | import { BinaryToTextEncoding, createHash, randomBytes } from 'crypto' |
10 | import { truncate } from 'lodash' | 10 | import { truncate } from 'lodash' |
11 | import { basename, isAbsolute, join, resolve } from 'path' | 11 | import { basename, extname, isAbsolute, join, resolve } from 'path' |
12 | import * as pem from 'pem' | 12 | import * as pem from 'pem' |
13 | import { pipeline } from 'stream' | 13 | import { pipeline } from 'stream' |
14 | import { URL } from 'url' | 14 | import { URL } from 'url' |
@@ -32,6 +32,18 @@ const objectConverter = (oldObject: any, keyConverter: (e: string) => string, va | |||
32 | return newObject | 32 | return newObject |
33 | } | 33 | } |
34 | 34 | ||
35 | function mapToJSON (map: Map<any, any>) { | ||
36 | const obj: any = {} | ||
37 | |||
38 | for (const [ k, v ] of map) { | ||
39 | obj[k] = v | ||
40 | } | ||
41 | |||
42 | return obj | ||
43 | } | ||
44 | |||
45 | // --------------------------------------------------------------------------- | ||
46 | |||
35 | const timeTable = { | 47 | const timeTable = { |
36 | ms: 1, | 48 | ms: 1, |
37 | second: 1000, | 49 | second: 1000, |
@@ -110,6 +122,8 @@ export function parseBytes (value: string | number): number { | |||
110 | } | 122 | } |
111 | } | 123 | } |
112 | 124 | ||
125 | // --------------------------------------------------------------------------- | ||
126 | |||
113 | function sanitizeUrl (url: string) { | 127 | function sanitizeUrl (url: string) { |
114 | const urlObject = new URL(url) | 128 | const urlObject = new URL(url) |
115 | 129 | ||
@@ -129,6 +143,8 @@ function sanitizeHost (host: string, remoteScheme: string) { | |||
129 | return host.replace(new RegExp(`:${toRemove}$`), '') | 143 | return host.replace(new RegExp(`:${toRemove}$`), '') |
130 | } | 144 | } |
131 | 145 | ||
146 | // --------------------------------------------------------------------------- | ||
147 | |||
132 | function isTestInstance () { | 148 | function isTestInstance () { |
133 | return process.env.NODE_ENV === 'test' | 149 | return process.env.NODE_ENV === 'test' |
134 | } | 150 | } |
@@ -141,6 +157,8 @@ function getAppNumber () { | |||
141 | return process.env.NODE_APP_INSTANCE | 157 | return process.env.NODE_APP_INSTANCE |
142 | } | 158 | } |
143 | 159 | ||
160 | // --------------------------------------------------------------------------- | ||
161 | |||
144 | let rootPath: string | 162 | let rootPath: string |
145 | 163 | ||
146 | function root () { | 164 | function root () { |
@@ -154,27 +172,19 @@ function root () { | |||
154 | return rootPath | 172 | return rootPath |
155 | } | 173 | } |
156 | 174 | ||
157 | function pageToStartAndCount (page: number, itemsPerPage: number) { | 175 | function buildPath (path: string) { |
158 | const start = (page - 1) * itemsPerPage | 176 | if (isAbsolute(path)) return path |
159 | 177 | ||
160 | return { start, count: itemsPerPage } | 178 | return join(root(), path) |
161 | } | 179 | } |
162 | 180 | ||
163 | function mapToJSON (map: Map<any, any>) { | 181 | function getLowercaseExtension (filename: string) { |
164 | const obj: any = {} | 182 | const ext = extname(filename) || '' |
165 | |||
166 | for (const [ k, v ] of map) { | ||
167 | obj[k] = v | ||
168 | } | ||
169 | 183 | ||
170 | return obj | 184 | return ext.toLowerCase() |
171 | } | 185 | } |
172 | 186 | ||
173 | function buildPath (path: string) { | 187 | // --------------------------------------------------------------------------- |
174 | if (isAbsolute(path)) return path | ||
175 | |||
176 | return join(root(), path) | ||
177 | } | ||
178 | 188 | ||
179 | // Consistent with .length, lodash truncate function is not | 189 | // Consistent with .length, lodash truncate function is not |
180 | function peertubeTruncate (str: string, options: { length: number, separator?: RegExp, omission?: string }) { | 190 | function peertubeTruncate (str: string, options: { length: number, separator?: RegExp, omission?: string }) { |
@@ -189,6 +199,27 @@ function peertubeTruncate (str: string, options: { length: number, separator?: R | |||
189 | return truncate(str, options) | 199 | return truncate(str, options) |
190 | } | 200 | } |
191 | 201 | ||
202 | function pageToStartAndCount (page: number, itemsPerPage: number) { | ||
203 | const start = (page - 1) * itemsPerPage | ||
204 | |||
205 | return { start, count: itemsPerPage } | ||
206 | } | ||
207 | |||
208 | // --------------------------------------------------------------------------- | ||
209 | |||
210 | type SemVersion = { major: number, minor: number, patch: number } | ||
211 | function parseSemVersion (s: string) { | ||
212 | const parsed = s.match(/^v?(\d+)\.(\d+)\.(\d+)$/i) | ||
213 | |||
214 | return { | ||
215 | major: parseInt(parsed[1]), | ||
216 | minor: parseInt(parsed[2]), | ||
217 | patch: parseInt(parsed[3]) | ||
218 | } as SemVersion | ||
219 | } | ||
220 | |||
221 | // --------------------------------------------------------------------------- | ||
222 | |||
192 | function sha256 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { | 223 | function sha256 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { |
193 | return createHash('sha256').update(str).digest(encoding) | 224 | return createHash('sha256').update(str).digest(encoding) |
194 | } | 225 | } |
@@ -197,6 +228,8 @@ function sha1 (str: string | Buffer, encoding: BinaryToTextEncoding = 'hex') { | |||
197 | return createHash('sha1').update(str).digest(encoding) | 228 | return createHash('sha1').update(str).digest(encoding) |
198 | } | 229 | } |
199 | 230 | ||
231 | // --------------------------------------------------------------------------- | ||
232 | |||
200 | function execShell (command: string, options?: ExecOptions) { | 233 | function execShell (command: string, options?: ExecOptions) { |
201 | return new Promise<{ err?: Error, stdout: string, stderr: string }>((res, rej) => { | 234 | return new Promise<{ err?: Error, stdout: string, stderr: string }>((res, rej) => { |
202 | exec(command, options, (err, stdout, stderr) => { | 235 | exec(command, options, (err, stdout, stderr) => { |
@@ -208,6 +241,8 @@ function execShell (command: string, options?: ExecOptions) { | |||
208 | }) | 241 | }) |
209 | } | 242 | } |
210 | 243 | ||
244 | // --------------------------------------------------------------------------- | ||
245 | |||
211 | function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { | 246 | function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { |
212 | return function promisified (): Promise<A> { | 247 | return function promisified (): Promise<A> { |
213 | return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { | 248 | return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { |
@@ -233,17 +268,6 @@ function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A) | |||
233 | } | 268 | } |
234 | } | 269 | } |
235 | 270 | ||
236 | type SemVersion = { major: number, minor: number, patch: number } | ||
237 | function parseSemVersion (s: string) { | ||
238 | const parsed = s.match(/^v?(\d+)\.(\d+)\.(\d+)$/i) | ||
239 | |||
240 | return { | ||
241 | major: parseInt(parsed[1]), | ||
242 | minor: parseInt(parsed[2]), | ||
243 | patch: parseInt(parsed[3]) | ||
244 | } as SemVersion | ||
245 | } | ||
246 | |||
247 | const randomBytesPromise = promisify1<number, Buffer>(randomBytes) | 271 | const randomBytesPromise = promisify1<number, Buffer>(randomBytes) |
248 | const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey) | 272 | const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey) |
249 | const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey) | 273 | const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey) |
@@ -259,17 +283,21 @@ export { | |||
259 | getAppNumber, | 283 | getAppNumber, |
260 | 284 | ||
261 | objectConverter, | 285 | objectConverter, |
286 | mapToJSON, | ||
287 | |||
262 | root, | 288 | root, |
263 | pageToStartAndCount, | 289 | buildPath, |
290 | getLowercaseExtension, | ||
264 | sanitizeUrl, | 291 | sanitizeUrl, |
265 | sanitizeHost, | 292 | sanitizeHost, |
266 | buildPath, | 293 | |
267 | execShell, | 294 | execShell, |
295 | |||
296 | pageToStartAndCount, | ||
268 | peertubeTruncate, | 297 | peertubeTruncate, |
269 | 298 | ||
270 | sha256, | 299 | sha256, |
271 | sha1, | 300 | sha1, |
272 | mapToJSON, | ||
273 | 301 | ||
274 | promisify0, | 302 | promisify0, |
275 | promisify1, | 303 | promisify1, |
diff --git a/server/helpers/express-utils.ts b/server/helpers/express-utils.ts index 010c6961a..003e02818 100644 --- a/server/helpers/express-utils.ts +++ b/server/helpers/express-utils.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import * as multer from 'multer' | 2 | import * as multer from 'multer' |
3 | import { extname } from 'path' | ||
4 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' | 3 | import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' |
5 | import { CONFIG } from '../initializers/config' | 4 | import { CONFIG } from '../initializers/config' |
6 | import { REMOTE_SCHEME } from '../initializers/constants' | 5 | import { REMOTE_SCHEME } from '../initializers/constants' |
6 | import { getLowercaseExtension } from './core-utils' | ||
7 | import { isArray } from './custom-validators/misc' | 7 | import { isArray } from './custom-validators/misc' |
8 | import { logger } from './logger' | 8 | import { logger } from './logger' |
9 | import { deleteFileAndCatch, generateRandomString } from './utils' | 9 | import { deleteFileAndCatch, generateRandomString } from './utils' |
@@ -79,7 +79,7 @@ function createReqFiles ( | |||
79 | 79 | ||
80 | filename: async (req, file, cb) => { | 80 | filename: async (req, file, cb) => { |
81 | let extension: string | 81 | let extension: string |
82 | const fileExtension = extname(file.originalname) | 82 | const fileExtension = getLowercaseExtension(file.originalname) |
83 | const extensionFromMimetype = getExtFromMimetype(mimeTypes, file.mimetype) | 83 | const extensionFromMimetype = getExtFromMimetype(mimeTypes, file.mimetype) |
84 | 84 | ||
85 | // Take the file extension if we don't understand the mime type | 85 | // Take the file extension if we don't understand the mime type |
diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts index 6f6f8d4da..122fb009d 100644 --- a/server/helpers/image-utils.ts +++ b/server/helpers/image-utils.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { copy, readFile, remove, rename } from 'fs-extra' | 1 | import { copy, readFile, remove, rename } from 'fs-extra' |
2 | import * as Jimp from 'jimp' | 2 | import * as Jimp from 'jimp' |
3 | import { extname } from 'path' | ||
4 | import { v4 as uuidv4 } from 'uuid' | 3 | import { v4 as uuidv4 } from 'uuid' |
4 | import { getLowercaseExtension } from './core-utils' | ||
5 | import { convertWebPToJPG, processGIF } from './ffmpeg-utils' | 5 | import { convertWebPToJPG, processGIF } from './ffmpeg-utils' |
6 | import { logger } from './logger' | 6 | import { logger } from './logger' |
7 | 7 | ||
@@ -15,7 +15,7 @@ async function processImage ( | |||
15 | newSize: { width: number, height: number }, | 15 | newSize: { width: number, height: number }, |
16 | keepOriginal = false | 16 | keepOriginal = false |
17 | ) { | 17 | ) { |
18 | const extension = extname(path) | 18 | const extension = getLowercaseExtension(path) |
19 | 19 | ||
20 | if (path === destination) { | 20 | if (path === destination) { |
21 | throw new Error('Jimp/FFmpeg needs an input path different that the output path.') | 21 | throw new Error('Jimp/FFmpeg needs an input path different that the output path.') |
@@ -61,7 +61,8 @@ async function jimpProcessor (path: string, destination: string, newSize: { widt | |||
61 | await remove(destination) | 61 | await remove(destination) |
62 | 62 | ||
63 | // Optimization if the source file has the appropriate size | 63 | // Optimization if the source file has the appropriate size |
64 | if (await skipProcessing({ jimpInstance, newSize, imageBytes: inputBuffer.byteLength, inputExt, outputExt: extname(destination) })) { | 64 | const outputExt = getLowercaseExtension(destination) |
65 | if (skipProcessing({ jimpInstance, newSize, imageBytes: inputBuffer.byteLength, inputExt, outputExt })) { | ||
65 | return copy(path, destination) | 66 | return copy(path, destination) |
66 | } | 67 | } |
67 | 68 | ||
diff --git a/server/lib/activitypub/actors/shared/object-to-model-attributes.ts b/server/lib/activitypub/actors/shared/object-to-model-attributes.ts index 66b22c952..f53b98448 100644 --- a/server/lib/activitypub/actors/shared/object-to-model-attributes.ts +++ b/server/lib/activitypub/actors/shared/object-to-model-attributes.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { extname } from 'path' | ||
2 | import { v4 as uuidv4 } from 'uuid' | 1 | import { v4 as uuidv4 } from 'uuid' |
2 | import { getLowercaseExtension } from '@server/helpers/core-utils' | ||
3 | import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc' | 3 | import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc' |
4 | import { MIMETYPES } from '@server/initializers/constants' | 4 | import { MIMETYPES } from '@server/initializers/constants' |
5 | import { ActorModel } from '@server/models/actor/actor' | 5 | import { ActorModel } from '@server/models/actor/actor' |
@@ -43,7 +43,7 @@ function getImageInfoFromObject (actorObject: ActivityPubActor, type: ActorImage | |||
43 | if (icon.mediaType) { | 43 | if (icon.mediaType) { |
44 | extension = mimetypes.MIMETYPE_EXT[icon.mediaType] | 44 | extension = mimetypes.MIMETYPE_EXT[icon.mediaType] |
45 | } else { | 45 | } else { |
46 | const tmp = extname(icon.url) | 46 | const tmp = getLowercaseExtension(icon.url) |
47 | 47 | ||
48 | if (mimetypes.EXT_MIMETYPE[tmp] !== undefined) extension = tmp | 48 | if (mimetypes.EXT_MIMETYPE[tmp] !== undefined) extension = tmp |
49 | } | 49 | } |
diff --git a/server/lib/job-queue/handlers/video-file-import.ts b/server/lib/job-queue/handlers/video-file-import.ts index 8297a1571..048963033 100644 --- a/server/lib/job-queue/handlers/video-file-import.ts +++ b/server/lib/job-queue/handlers/video-file-import.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { copy, stat } from 'fs-extra' | 2 | import { copy, stat } from 'fs-extra' |
3 | import { extname } from 'path' | 3 | import { extname } from 'path' |
4 | import { getLowercaseExtension } from '@server/helpers/core-utils' | ||
4 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 5 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
5 | import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' | 6 | import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' |
6 | import { UserModel } from '@server/models/user/user' | 7 | import { UserModel } from '@server/models/user/user' |
@@ -55,7 +56,7 @@ async function updateVideoFile (video: MVideoFullLight, inputFilePath: string) { | |||
55 | const { size } = await stat(inputFilePath) | 56 | const { size } = await stat(inputFilePath) |
56 | const fps = await getVideoFileFPS(inputFilePath) | 57 | const fps = await getVideoFileFPS(inputFilePath) |
57 | 58 | ||
58 | const fileExt = extname(inputFilePath) | 59 | const fileExt = getLowercaseExtension(inputFilePath) |
59 | 60 | ||
60 | const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === videoFileResolution) | 61 | const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === videoFileResolution) |
61 | 62 | ||
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index d71053e87..937f586c9 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { move, remove, stat } from 'fs-extra' | 2 | import { move, remove, stat } from 'fs-extra' |
3 | import { extname } from 'path' | 3 | import { extname } from 'path' |
4 | import { getLowercaseExtension } from '@server/helpers/core-utils' | ||
4 | import { retryTransactionWrapper } from '@server/helpers/database-utils' | 5 | import { retryTransactionWrapper } from '@server/helpers/database-utils' |
5 | import { YoutubeDL } from '@server/helpers/youtube-dl' | 6 | import { YoutubeDL } from '@server/helpers/youtube-dl' |
6 | import { isPostImportVideoAccepted } from '@server/lib/moderation' | 7 | import { isPostImportVideoAccepted } from '@server/lib/moderation' |
@@ -119,7 +120,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: MVid | |||
119 | const duration = await getDurationFromVideoFile(tempVideoPath) | 120 | const duration = await getDurationFromVideoFile(tempVideoPath) |
120 | 121 | ||
121 | // Prepare video file object for creation in database | 122 | // Prepare video file object for creation in database |
122 | const fileExt = extname(tempVideoPath) | 123 | const fileExt = getLowercaseExtension(tempVideoPath) |
123 | const videoFileData = { | 124 | const videoFileData = { |
124 | extname: fileExt, | 125 | extname: fileExt, |
125 | resolution: videoFileResolution, | 126 | resolution: videoFileResolution, |
diff --git a/server/lib/local-actor.ts b/server/lib/local-actor.ts index 55e77dd04..2d2bd43a1 100644 --- a/server/lib/local-actor.ts +++ b/server/lib/local-actor.ts | |||
@@ -1,8 +1,9 @@ | |||
1 | import 'multer' | 1 | import 'multer' |
2 | import { queue } from 'async' | 2 | import { queue } from 'async' |
3 | import * as LRUCache from 'lru-cache' | 3 | import * as LRUCache from 'lru-cache' |
4 | import { extname, join } from 'path' | 4 | import { join } from 'path' |
5 | import { v4 as uuidv4 } from 'uuid' | 5 | import { v4 as uuidv4 } from 'uuid' |
6 | import { getLowercaseExtension } from '@server/helpers/core-utils' | ||
6 | import { ActorModel } from '@server/models/actor/actor' | 7 | import { ActorModel } from '@server/models/actor/actor' |
7 | import { ActivityPubActorType, ActorImageType } from '@shared/models' | 8 | import { ActivityPubActorType, ActorImageType } from '@shared/models' |
8 | import { retryTransactionWrapper } from '../helpers/database-utils' | 9 | import { retryTransactionWrapper } from '../helpers/database-utils' |
@@ -41,7 +42,7 @@ async function updateLocalActorImageFile ( | |||
41 | ? ACTOR_IMAGES_SIZE.AVATARS | 42 | ? ACTOR_IMAGES_SIZE.AVATARS |
42 | : ACTOR_IMAGES_SIZE.BANNERS | 43 | : ACTOR_IMAGES_SIZE.BANNERS |
43 | 44 | ||
44 | const extension = extname(imagePhysicalFile.filename) | 45 | const extension = getLowercaseExtension(imagePhysicalFile.filename) |
45 | 46 | ||
46 | const imageName = uuidv4() + extension | 47 | const imageName = uuidv4() + extension |
47 | const destination = join(CONFIG.STORAGE.ACTOR_IMAGES, imageName) | 48 | const destination = join(CONFIG.STORAGE.ACTOR_IMAGES, imageName) |
diff --git a/server/models/actor/actor.ts b/server/models/actor/actor.ts index 65c53f8f8..0cd30f545 100644 --- a/server/models/actor/actor.ts +++ b/server/models/actor/actor.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | import { values } from 'lodash' | 1 | import { values } from 'lodash' |
2 | import { extname } from 'path' | ||
3 | import { literal, Op, Transaction } from 'sequelize' | 2 | import { literal, Op, Transaction } from 'sequelize' |
4 | import { | 3 | import { |
5 | AllowNull, | 4 | AllowNull, |
@@ -17,6 +16,7 @@ import { | |||
17 | Table, | 16 | Table, |
18 | UpdatedAt | 17 | UpdatedAt |
19 | } from 'sequelize-typescript' | 18 | } from 'sequelize-typescript' |
19 | import { getLowercaseExtension } from '@server/helpers/core-utils' | ||
20 | import { ModelCache } from '@server/models/model-cache' | 20 | import { ModelCache } from '@server/models/model-cache' |
21 | import { AttributesOnly } from '@shared/core-utils' | 21 | import { AttributesOnly } from '@shared/core-utils' |
22 | import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub' | 22 | import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub' |
@@ -567,7 +567,7 @@ export class ActorModel extends Model<Partial<AttributesOnly<ActorModel>>> { | |||
567 | let image: ActivityIconObject | 567 | let image: ActivityIconObject |
568 | 568 | ||
569 | if (this.avatarId) { | 569 | if (this.avatarId) { |
570 | const extension = extname(this.Avatar.filename) | 570 | const extension = getLowercaseExtension(this.Avatar.filename) |
571 | 571 | ||
572 | icon = { | 572 | icon = { |
573 | type: 'Image', | 573 | type: 'Image', |
@@ -580,7 +580,7 @@ export class ActorModel extends Model<Partial<AttributesOnly<ActorModel>>> { | |||
580 | 580 | ||
581 | if (this.bannerId) { | 581 | if (this.bannerId) { |
582 | const banner = (this as MActorAPChannel).Banner | 582 | const banner = (this as MActorAPChannel).Banner |
583 | const extension = extname(banner.filename) | 583 | const extension = getLowercaseExtension(banner.filename) |
584 | 584 | ||
585 | image = { | 585 | image = { |
586 | type: 'Image', | 586 | type: 'Image', |
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 98a568a02..a3a276188 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts | |||
@@ -4,10 +4,11 @@ import { expect } from 'chai' | |||
4 | import { createReadStream, pathExists, readdir, readFile, stat } from 'fs-extra' | 4 | import { createReadStream, pathExists, readdir, readFile, stat } from 'fs-extra' |
5 | import got, { Response as GotResponse } from 'got/dist/source' | 5 | import got, { Response as GotResponse } from 'got/dist/source' |
6 | import * as parseTorrent from 'parse-torrent' | 6 | import * as parseTorrent from 'parse-torrent' |
7 | import { extname, join } from 'path' | 7 | import { join } from 'path' |
8 | import * as request from 'supertest' | 8 | import * as request from 'supertest' |
9 | import { v4 as uuidv4 } from 'uuid' | 9 | import { v4 as uuidv4 } from 'uuid' |
10 | import validator from 'validator' | 10 | import validator from 'validator' |
11 | import { getLowercaseExtension } from '@server/helpers/core-utils' | ||
11 | import { HttpStatusCode } from '@shared/core-utils' | 12 | import { HttpStatusCode } from '@shared/core-utils' |
12 | import { VideosCommonQuery } from '@shared/models' | 13 | import { VideosCommonQuery } from '@shared/models' |
13 | import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' | 14 | import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' |
@@ -738,7 +739,7 @@ async function completeVideoCheck ( | |||
738 | const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution) | 739 | const file = videoDetails.files.find(f => f.resolution.id === attributeFile.resolution) |
739 | expect(file).not.to.be.undefined | 740 | expect(file).not.to.be.undefined |
740 | 741 | ||
741 | let extension = extname(attributes.fixture) | 742 | let extension = getLowercaseExtension(attributes.fixture) |
742 | // Transcoding enabled: extension will always be .mp4 | 743 | // Transcoding enabled: extension will always be .mp4 |
743 | if (attributes.files.length > 1) extension = '.mp4' | 744 | if (attributes.files.length > 1) extension = '.mp4' |
744 | 745 | ||