diff --git a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts index e8e9b5018..4fd196ad6 100644 --- a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts +++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts @@ -21,7 +21,7 @@ export class ActorAvatarComponent implements OnInit, OnChanges { @Input() previewImage: string - @Input({ transform: numberAttribute }) size: number + @Input({ transform: numberAttribute }) size = 120 // Use an external link @Input() href: string diff --git a/packages/server-commands/src/server/config-command.ts b/packages/server-commands/src/server/config-command.ts index 3a550eb55..cd3fc6f44 100644 --- a/packages/server-commands/src/server/config-command.ts +++ b/packages/server-commands/src/server/config-command.ts @@ -30,6 +30,16 @@ export class ConfigCommand extends AbstractCommand { } } + static getDisableRatesLimitOverrideConfig () { + return { + rates_limit: { + api: { + max: 5000 + } + } + } + } + // --------------------------------------------------------------------------- enableSignup (requiresApproval: boolean, limit = -1) { diff --git a/packages/tests/fixtures/avatar-resized-1500x1500.png b/packages/tests/fixtures/avatar-resized-1500x1500.png new file mode 100644 index 000000000..97135debd Binary files /dev/null and b/packages/tests/fixtures/avatar-resized-1500x1500.png differ diff --git a/packages/tests/fixtures/avatar-resized-600x600.png b/packages/tests/fixtures/avatar-resized-600x600.png new file mode 100644 index 000000000..2e42135ee Binary files /dev/null and b/packages/tests/fixtures/avatar-resized-600x600.png differ diff --git a/packages/tests/fixtures/avatar2-resized-1500x1500.png b/packages/tests/fixtures/avatar2-resized-1500x1500.png new file mode 100644 index 000000000..29ac06245 Binary files /dev/null and b/packages/tests/fixtures/avatar2-resized-1500x1500.png differ diff --git a/packages/tests/fixtures/avatar2-resized-600x600.png b/packages/tests/fixtures/avatar2-resized-600x600.png new file mode 100644 index 000000000..95ee56fa4 Binary files /dev/null and b/packages/tests/fixtures/avatar2-resized-600x600.png differ diff --git a/packages/tests/src/api/server/config.ts b/packages/tests/src/api/server/config.ts index 8aaf9348f..f867c9ee8 100644 --- a/packages/tests/src/api/server/config.ts +++ b/packages/tests/src/api/server/config.ts @@ -11,7 +11,7 @@ import { PeerTubeServer, setAccessTokensToServers } from '@peertube/peertube-server-commands' -import { testFileExistsOrNot, testImage, testImageSize } from '@tests/shared/checks.js' +import { testFileExistsOrNot, testImage, testAvatarSize } from '@tests/shared/checks.js' import { basename } from 'path' function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) { @@ -739,7 +739,7 @@ describe('Test config', function () { const { avatars } = await checkAndGetServerImages() for (const avatar of avatars) { - await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, extension) + await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` }) } avatarPath = avatars[0].path diff --git a/packages/tests/src/api/users/index.ts b/packages/tests/src/api/users/index.ts index 7bda4a3e0..3b8008ca8 100644 --- a/packages/tests/src/api/users/index.ts +++ b/packages/tests/src/api/users/index.ts @@ -1,5 +1,5 @@ import './oauth.js' -import './registrations`.js' +import './registrations.js' import './two-factor.js' import './user-export.js' import './user-import.js' diff --git a/packages/tests/src/api/users/user-export.ts b/packages/tests/src/api/users/user-export.ts index b76933f07..1bb6c2f36 100644 --- a/packages/tests/src/api/users/user-export.ts +++ b/packages/tests/src/api/users/user-export.ts @@ -435,7 +435,7 @@ function runTest (withObjectStorage: boolean) { expect(secondaryChannel.description).to.equal('noah description') expect(secondaryChannel.support).to.equal('noah support') - expect(secondaryChannel.avatars).to.have.lengthOf(2) + expect(secondaryChannel.avatars).to.have.lengthOf(4) expect(secondaryChannel.banners).to.have.lengthOf(1) const urls = [ ...secondaryChannel.avatars, ...secondaryChannel.banners ].map(a => a.url) @@ -627,7 +627,7 @@ function runTest (withObjectStorage: boolean) { // PeerTube format { const json = await parseZIPJSONFile(zip, 'peertube/account.json') - expect(json.avatars).to.have.lengthOf(2) + expect(json.avatars).to.have.lengthOf(4) for (const avatar of json.avatars) { await makeRawRequest({ url: avatar.url, expectedStatus: HttpStatusCode.OK_200 }) diff --git a/packages/tests/src/api/users/user-import.ts b/packages/tests/src/api/users/user-import.ts index aad6b2898..798d04220 100644 --- a/packages/tests/src/api/users/user-import.ts +++ b/packages/tests/src/api/users/user-import.ts @@ -21,7 +21,7 @@ import { areMockObjectStorageTestsDisabled } from '@peertube/peertube-node-utils import { writeFile } from 'fs/promises' import { join } from 'path' import { expect } from 'chai' -import { testImage, testImageSize } from '@tests/shared/checks.js' +import { testImage, testAvatarSize } from '@tests/shared/checks.js' import { completeVideoCheck } from '@tests/shared/videos.js' import { completeCheckHlsPlaylist } from '@tests/shared/streaming-playlists.js' @@ -84,7 +84,7 @@ function runTest (withObjectStorage: boolean) { } // Add avatars - await server.users.updateMyAvatar({ token: noahToken, fixture: 'avatar.gif' }) + await server.users.updateMyAvatar({ token: noahToken, fixture: 'avatar.png' }) // Add password protected video await server.videos.upload({ @@ -168,9 +168,10 @@ function runTest (withObjectStorage: boolean) { expect(me.account.displayName).to.equal('noah') expect(me.username).to.equal('noah_remote') expect(me.account.description).to.equal('super noah description') + expect(me.account.avatars).to.have.lengthOf(4) for (const avatar of me.account.avatars) { - await testImageSize(remoteServer.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, '.gif') + await testAvatarSize({ url: remoteServer.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` }) } }) @@ -482,7 +483,7 @@ function runTest (withObjectStorage: boolean) { // My avatars { const me = await remoteServer.users.getMyInfo({ token: remoteNoahToken }) - expect(me.account.avatars).to.have.lengthOf(2) + expect(me.account.avatars).to.have.lengthOf(4) } // Channels diff --git a/packages/tests/src/api/users/users.ts b/packages/tests/src/api/users/users.ts index cf26f444c..af4f19340 100644 --- a/packages/tests/src/api/users/users.ts +++ b/packages/tests/src/api/users/users.ts @@ -1,9 +1,13 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ import { expect } from 'chai' -import { testImageSize } from '@tests/shared/checks.js' +import { testAvatarSize } from '@tests/shared/checks.js' import { AbuseState, HttpStatusCode, UserAdminFlag, UserRole, VideoPlaylistType } from '@peertube/peertube-models' -import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@peertube/peertube-server-commands' +import { + cleanupTests, + createSingleServer, PeerTubeServer, + setAccessTokensToServers +} from '@peertube/peertube-server-commands' describe('Test users', function () { let server: PeerTubeServer @@ -264,7 +268,7 @@ describe('Test users', function () { const user = await server.users.getMyInfo({ token: userToken }) for (const avatar of user.account.avatars) { - await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, '.gif') + await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` }) } }) @@ -276,7 +280,7 @@ describe('Test users', function () { const user = await server.users.getMyInfo({ token: userToken }) for (const avatar of user.account.avatars) { - await testImageSize(server.url, `avatar-resized-${avatar.width}x${avatar.width}`, avatar.path, extension) + await testAvatarSize({ url: server.url, avatar, imageName: `avatar-resized-${avatar.width}x${avatar.width}` }) } } }) diff --git a/packages/tests/src/api/videos/multiple-servers.ts b/packages/tests/src/api/videos/multiple-servers.ts index 5073e3129..6c62a1d95 100644 --- a/packages/tests/src/api/videos/multiple-servers.ts +++ b/packages/tests/src/api/videos/multiple-servers.ts @@ -131,13 +131,13 @@ describe('Test multiple servers', function () { await completeVideoCheck({ server, originServer: servers[0], videoUUID: video.uuid, attributes: checkAttributes }) publishedAt = video.publishedAt as string - expect(video.channel.avatars).to.have.lengthOf(2) - expect(video.account.avatars).to.have.lengthOf(2) + expect(video.channel.avatars).to.have.lengthOf(4) + expect(video.account.avatars).to.have.lengthOf(4) for (const image of [ ...video.channel.avatars, ...video.account.avatars ]) { expect(image.createdAt).to.exist expect(image.updatedAt).to.exist - expect(image.width).to.be.above(20).and.below(1000) + expect(image.width).to.be.above(20).and.below(2000) expect(image.path).to.exist await makeGetRequest({ diff --git a/packages/tests/src/api/videos/video-comments.ts b/packages/tests/src/api/videos/video-comments.ts index f17db9979..7b21287e4 100644 --- a/packages/tests/src/api/videos/video-comments.ts +++ b/packages/tests/src/api/videos/video-comments.ts @@ -257,7 +257,7 @@ describe('Test video comments', function () { expect(data[0].text).to.equal('my second answer to thread 4') expect(data[0].account.name).to.equal('root') expect(data[0].account.displayName).to.equal('root') - expect(data[0].account.avatars).to.have.lengthOf(2) + expect(data[0].account.avatars).to.have.lengthOf(4) } { @@ -266,8 +266,8 @@ describe('Test video comments', function () { expect(total).to.equal(7) expect(data).to.have.lengthOf(2) - expect(data[0].account.avatars).to.have.lengthOf(2) - expect(data[1].account.avatars).to.have.lengthOf(2) + expect(data[0].account.avatars).to.have.lengthOf(4) + expect(data[1].account.avatars).to.have.lengthOf(4) } }) diff --git a/packages/tests/src/cli/prune-storage.ts b/packages/tests/src/cli/prune-storage.ts index c07a2a975..f3d7d19f2 100644 --- a/packages/tests/src/cli/prune-storage.ts +++ b/packages/tests/src/cli/prune-storage.ts @@ -46,7 +46,7 @@ async function assertCountAreOkay (servers: PeerTubeServer[]) { expect(thumbnailsCount).to.equal(5) // 3 local videos, 1 local playlist, 2 remotes videos (lazy downloaded) and 1 remote playlist const avatarsCount = await server.servers.countFiles('avatars') - expect(avatarsCount).to.equal(4) + expect(avatarsCount).to.equal(8) const hlsRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls')) expect(hlsRootCount).to.equal(3) // 2 videos + private directory diff --git a/packages/tests/src/shared/checks.ts b/packages/tests/src/shared/checks.ts index fea618a30..0f1d9d02e 100644 --- a/packages/tests/src/shared/checks.ts +++ b/packages/tests/src/shared/checks.ts @@ -3,7 +3,7 @@ import { expect } from 'chai' import { pathExists } from 'fs-extra/esm' import { readFile } from 'fs/promises' -import { join } from 'path' +import { join, parse } from 'path' import { HttpStatusCode } from '@peertube/peertube-models' import { buildAbsoluteFixturePath } from '@peertube/peertube-node-utils' import { makeGetRequest, PeerTubeServer } from '@peertube/peertube-server-commands' @@ -42,14 +42,25 @@ async function expectLogContain (server: PeerTubeServer, str: string) { expect(content.toString()).to.contain(str) } -async function testImageSize (url: string, imageName: string, imageHTTPPath: string, extension = '.jpg') { - const res = await makeGetRequest({ +async function testAvatarSize (options: { + url: string + imageName: string + avatar: { + width: number + path: string + } +}) { + const { url, imageName, avatar } = options + + const { body } = await makeGetRequest({ url, - path: imageHTTPPath, + path: avatar.path, expectedStatus: HttpStatusCode.OK_200 }) - const body = res.body + const extension = parse(avatar.path).ext + // We don't test big GIF avatars + if (extension === '.gif' && avatar.width > 150) return const data = await readFile(buildAbsoluteFixturePath(imageName + extension)) const minLength = data.length - ((40 * data.length) / 100) @@ -162,7 +173,7 @@ async function checkVideoDuration (server: PeerTubeServer, videoUUID: string, du export { dateIsValid, testImageGeneratedByFFmpeg, - testImageSize, + testAvatarSize, testImage, expectLogDoesNotContain, testFileExistsOrNot, diff --git a/packages/tests/src/shared/import-export.ts b/packages/tests/src/shared/import-export.ts index 2c42aa264..a620a7032 100644 --- a/packages/tests/src/shared/import-export.ts +++ b/packages/tests/src/shared/import-export.ts @@ -127,9 +127,15 @@ export async function prepareImportExportTests (options: { const emailPort = await MockSmtpServer.Instance.collectEmails(emails) + const overrideConfig = { + ...objectStorageConfig, + ...ConfigCommand.getEmailOverrideConfig(emailPort), + ...ConfigCommand.getDisableRatesLimitOverrideConfig() + } + const [ server, remoteServer, blockedServer ] = await Promise.all([ - createSingleServer(1, { ...objectStorageConfig, ...ConfigCommand.getEmailOverrideConfig(emailPort) }), - createSingleServer(2, { ...objectStorageConfig, ...ConfigCommand.getEmailOverrideConfig(emailPort) }), + createSingleServer(1, overrideConfig), + createSingleServer(2, overrideConfig), withBlockedServer ? createSingleServer(3) diff --git a/packages/tests/src/shared/notifications.ts b/packages/tests/src/shared/notifications.ts index be471163b..c3612f790 100644 --- a/packages/tests/src/shared/notifications.ts +++ b/packages/tests/src/shared/notifications.ts @@ -933,7 +933,7 @@ function checkActor (actor: any, options: { withAvatar?: boolean } = {}) { if (withAvatar) { expect(actor.avatars).to.be.an('array') - expect(actor.avatars).to.have.lengthOf(2) + expect(actor.avatars).to.have.lengthOf(4) expect(actor.avatars[0].path).to.exist.and.not.empty } } diff --git a/server/core/helpers/image-utils.ts b/server/core/helpers/image-utils.ts index e8c637e2a..9a99dffc9 100644 --- a/server/core/helpers/image-utils.ts +++ b/server/core/helpers/image-utils.ts @@ -31,7 +31,7 @@ export async function processImage (options: { if (extension === '.gif') { await processGIF({ path, destination, newSize }) } else { - await jimpProcessor(path, destination, newSize, extension) + await jimpProcessor({ path, destination, newSize, inputExt: extension }) } if (keepOriginal !== true) await remove(path) @@ -56,7 +56,17 @@ export async function getImageSize (path: string) { // Private // --------------------------------------------------------------------------- -async function jimpProcessor (path: string, destination: string, newSize: { width: number, height: number }, inputExt: string) { +async function jimpProcessor (options: { + path: string + destination: string + newSize: { + width: number + height: number + } + inputExt: string +}) { + const { path, destination, newSize, inputExt } = options + let sourceImage: Jimp const inputBuffer = await readFile(path) @@ -125,7 +135,7 @@ function skipProcessing (options: { const { width, height } = newSize if (hasExif(sourceImage)) return false - if (sourceImage.getWidth() > width || sourceImage.getHeight() > height) return false + if (sourceImage.getWidth() !== width || sourceImage.getHeight() !== height) return false if (inputExt !== outputExt) return false const kB = 1000 diff --git a/server/core/initializers/constants.ts b/server/core/initializers/constants.ts index 26d9bc115..0fb0710aa 100644 --- a/server/core/initializers/constants.ts +++ b/server/core/initializers/constants.ts @@ -882,6 +882,14 @@ const PREVIEWS_SIZE = { } const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = { [ActorImageType.AVATAR]: [ + { + width: 1500, + height: 1500 + }, + { + width: 600, + height: 600 + }, { width: 120, height: 120