diff --git a/.config/example.yml b/.config/example.yml index 38d5e59ea7966425ca33860f8442fa3ebc136287..4da73993592db7409314c5c233a652b94e7f958d 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -155,6 +155,9 @@ id: 'aid' # Media Proxy #mediaProxy: https://example.com/proxy +# Proxy remote files (default: false) +#proxyRemoteFiles: true + # Sign to ActivityPub GET request (default: false) #signToActivityPubGet: true diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index cdfdfcec9e8114491e524a4706d6b51258ba29f2..af88f382ef55e5afce9731fad135f4ec60d43f42 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -325,8 +325,6 @@ disablingTimelinesInfo: "ã“れらã®ã‚¿ã‚¤ãƒ ラインを無効化ã—ã¦ã‚‚〠registration: "登録" enableRegistration: "誰ã§ã‚‚æ–°è¦ç™»éŒ²ã§ãるよã†ã«ã™ã‚‹" invite: "招待" -proxyRemoteFiles: "リモートã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’プãƒã‚ã‚·ã™ã‚‹" -proxyRemoteFilesDescription: "ã“ã®è¨å®šã‚’有効ã«ã™ã‚‹ã¨ã€æœªä¿å˜ã¾ãŸã¯ä¿å˜å®¹é‡è¶…éŽã§å‰Šé™¤ã•ã‚ŒãŸãƒªãƒ¢ãƒ¼ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚’ãƒãƒ¼ã‚«ãƒ«ã§ãƒ—ãƒã‚ã‚·ã—ã€ã‚µãƒ ãƒã‚¤ãƒ«ã‚‚生æˆã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚サーãƒãƒ¼ã®ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã«ã¯å½±éŸ¿ã—ã¾ã›ã‚“ã€" driveCapacityPerLocalAccount: "ãƒãƒ¼ã‚«ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã²ã¨ã‚Šã‚ãŸã‚Šã®ãƒ‰ãƒ©ã‚¤ãƒ–容é‡" driveCapacityPerRemoteAccount: "リモートユーザーã²ã¨ã‚Šã‚ãŸã‚Šã®ãƒ‰ãƒ©ã‚¤ãƒ–容é‡" inMb: "メガãƒã‚¤ãƒˆå˜ä½" diff --git a/packages/backend/migration/1626509500668-fix-remote-file-proxy.js b/packages/backend/migration/1626509500668-fix-remote-file-proxy.js new file mode 100644 index 0000000000000000000000000000000000000000..163f73c66f686712012ad53812fac35409181b44 --- /dev/null +++ b/packages/backend/migration/1626509500668-fix-remote-file-proxy.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class fixRemoteFileProxy1626509500668 { + constructor() { + this.name = 'fixRemoteFileProxy1626509500668'; + } + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarUrl"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "bannerUrl"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "avatarBlurhash"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "bannerBlurhash"`); + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "proxyRemoteFiles"`); + } + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "user" ADD "bannerBlurhash" character varying(128)`); + await queryRunner.query(`ALTER TABLE "user" ADD "avatarBlurhash" character varying(128)`); + await queryRunner.query(`ALTER TABLE "user" ADD "bannerUrl" character varying(512)`); + await queryRunner.query(`ALTER TABLE "user" ADD "avatarUrl" character varying(512)`); + } +} + +exports.fixRemoteFileProxy1626509500668 = fixRemoteFileProxy1626509500668; diff --git a/packages/backend/src/config/types.ts b/packages/backend/src/config/types.ts index e3ca6c1ab62efe34235a39bee45775f6f728cfb6..7a1b83c99b46dd7f9a6c7dc23f50caadeb8e1ecb 100644 --- a/packages/backend/src/config/types.ts +++ b/packages/backend/src/config/types.ts @@ -62,6 +62,7 @@ export type Source = { }; mediaProxy?: string; + proxyRemoteFiles?: boolean; signToActivityPubGet?: boolean; }; diff --git a/packages/backend/src/models/entities/meta.ts b/packages/backend/src/models/entities/meta.ts index 4328c8fbf8cfbf6ca7ee1529e541429e30ef0ac3..0b1e9c85c30883578235ac264c40435b46546fd6 100644 --- a/packages/backend/src/models/entities/meta.ts +++ b/packages/backend/src/models/entities/meta.ts @@ -137,11 +137,6 @@ export class Meta { }) public cacheRemoteFiles: boolean; - @Column('boolean', { - default: false, - }) - public proxyRemoteFiles: boolean; - @Column({ ...id(), nullable: true, diff --git a/packages/backend/src/models/entities/user.ts b/packages/backend/src/models/entities/user.ts index 3eecde1f17221911f6005301b0f8d75834793f70..9d5db10eb34f536e63aaac4d2b4c5361d1ec55a8 100644 --- a/packages/backend/src/models/entities/user.ts +++ b/packages/backend/src/models/entities/user.ts @@ -106,26 +106,6 @@ export class User { }) public tags: string[]; - @Column('varchar', { - length: 512, nullable: true, - }) - public avatarUrl: string | null; - - @Column('varchar', { - length: 512, nullable: true, - }) - public bannerUrl: string | null; - - @Column('varchar', { - length: 128, nullable: true, - }) - public avatarBlurhash: string | null; - - @Column('varchar', { - length: 128, nullable: true, - }) - public bannerBlurhash: string | null; - @Column('boolean', { default: false, comment: 'Whether the User is suspended.', diff --git a/packages/backend/src/models/repositories/drive-file.ts b/packages/backend/src/models/repositories/drive-file.ts index 27afe435e6fcace3e1981fed6be29ff98ef05732..6452632db70884a0c9abf01b3d8aa3e979bf8e5c 100644 --- a/packages/backend/src/models/repositories/drive-file.ts +++ b/packages/backend/src/models/repositories/drive-file.ts @@ -41,7 +41,7 @@ export class DriveFileRepository extends Repository<DriveFile> { return file.properties; } - public getPublicUrl(file: DriveFile, thumbnail = false, meta?: Meta): string | null { + public getPublicUrl(file: DriveFile, thumbnail = false): string | null { // リモートã‹ã¤ãƒ¡ãƒ‡ã‚£ã‚¢ãƒ—ãƒã‚ã‚· if (file.uri != null && file.userHost != null && config.mediaProxy != null) { return appendQuery(config.mediaProxy, query({ @@ -51,7 +51,7 @@ export class DriveFileRepository extends Repository<DriveFile> { } // リモートã‹ã¤æœŸé™åˆ‡ã‚Œã¯ãƒãƒ¼ã‚«ãƒ«ãƒ—ãƒã‚シを試ã¿ã‚‹ - if (file.uri != null && file.isLink && meta && meta.proxyRemoteFiles) { + if (file.uri != null && file.isLink && config.proxyRemoteFiles) { const key = thumbnail ? file.thumbnailAccessKey : file.webpublicAccessKey; if (key && !key.match('/')) { // å¤ã„ã‚‚ã®ã¯ã“ã“ã«ã‚ªãƒ–ジェクトストレージã‚ーãŒå…¥ã£ã¦ã‚‹ã®ã§é™¤å¤– @@ -136,8 +136,8 @@ export class DriveFileRepository extends Repository<DriveFile> { isSensitive: file.isSensitive, blurhash: file.blurhash, properties: opts.self ? file.properties : this.getPublicProperties(file), - url: opts.self ? file.url : this.getPublicUrl(file, false, meta), - thumbnailUrl: this.getPublicUrl(file, true, meta), + url: opts.self ? file.url : this.getPublicUrl(file, false), + thumbnailUrl: this.getPublicUrl(file, true), comment: file.comment, folderId: file.folderId, folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, { diff --git a/packages/backend/src/models/repositories/note-reaction.ts b/packages/backend/src/models/repositories/note-reaction.ts index e83e753ec84c76477da36642b32097ba368108ef..a212b0d3e9a37cd763aab2b88f61b6f18749b99e 100644 --- a/packages/backend/src/models/repositories/note-reaction.ts +++ b/packages/backend/src/models/repositories/note-reaction.ts @@ -23,10 +23,10 @@ export class NoteReactionRepository extends Repository<NoteReaction> { return { id: reaction.id, createdAt: reaction.createdAt.toISOString(), - user: await Users.pack(reaction.userId, me), + user: await Users.pack(reaction.user ?? reaction.userId, me), type: convertLegacyReaction(reaction.reaction), ...(opts.withNote ? { - note: await Notes.pack(reaction.noteId, me), + note: await Notes.pack(reaction.note ?? reaction.noteId, me), } : {}), }; } diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index 478b1ac2870c5ffbc09acebc45098a36a4cf2719..a909ab3ba682dcb43c7b911c37246f97183b41d4 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -1,7 +1,7 @@ import { EntityRepository, Repository, In, Not } from 'typeorm'; import Ajv from 'ajv'; import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js'; -import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index.js'; +import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index.js'; import config from '@/config/index.js'; import { Packed } from '@/misc/schema.js'; import { awaitAll, Promiseable } from '@/prelude/await-all.js'; @@ -182,13 +182,18 @@ export class UserRepository extends Repository<User> { } public getAvatarUrl(user: User): string { - if (user.avatarUrl) { - return user.avatarUrl; + // TODO: avatarIdãŒã‚ã‚‹ãŒavatarãŒãªã„(JOINã•ã‚Œã¦ãªã„)å ´åˆã®ãƒãƒ³ãƒ‰ãƒªãƒ³ã‚° + if (user.avatar) { + return DriveFiles.getPublicUrl(user.avatar, true) || this.getIdenticonUrl(user.id); } else { - return `${config.url}/identicon/${user.id}`; + return this.getIdenticonUrl(user.id); } } + public getIdenticonUrl(userId: User['id']): string { + return `${config.url}/identicon/${userId}`; + } + public async pack<ExpectsMe extends boolean | null = null, D extends boolean = false>( src: User['id'] | User, me?: { id: User['id'] } | null | undefined, @@ -202,7 +207,18 @@ export class UserRepository extends Repository<User> { includeSecrets: false, }, options); - const user = typeof src === 'object' ? src : await this.findOneOrFail(src); + let user: User; + + if (typeof src === 'object') { + user = src; + if (src.avatar === undefined && src.avatarId) src.avatar = await DriveFiles.findOne(src.avatarId) ?? null; + if (src.banner === undefined && src.bannerId) src.banner = await DriveFiles.findOne(src.bannerId) ?? null; + } else { + user = await this.findOneOrFail(src, { + relations: ['avatar', 'banner'], + }); + } + const meId = me ? me.id : null; const isMe = meId === user.id; @@ -232,7 +248,7 @@ export class UserRepository extends Repository<User> { username: user.username, host: user.host, avatarUrl: this.getAvatarUrl(user), - avatarBlurhash: user.avatarBlurhash, + avatarBlurhash: user.avatar?.blurhash || null, avatarColor: null, // 後方互æ›æ€§ã®ãŸã‚ isAdmin: user.isAdmin || falsy, isModerator: user.isModerator || falsy, @@ -256,8 +272,8 @@ export class UserRepository extends Repository<User> { createdAt: user.createdAt.toISOString(), updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null, - bannerUrl: user.bannerUrl, - bannerBlurhash: user.bannerBlurhash, + bannerUrl: user.banner ? DriveFiles.getPublicUrl(user.banner, false) : null, + bannerBlurhash: user.banner?.blurhash || null, bannerColor: null, // 後方互æ›æ€§ã®ãŸã‚ isLocked: user.isLocked, isSilenced: user.isSilenced || falsy, diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 1c03bddccc9d92e3af01fe53bdf5d356ebf69675..bfc613523b94bf0e4e06829c1c83321dbfc65b89 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -228,26 +228,14 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us const avatarId = avatar ? avatar.id : null; const bannerId = banner ? banner.id : null; - const avatarUrl = avatar ? DriveFiles.getPublicUrl(avatar, true) : null; - const bannerUrl = banner ? DriveFiles.getPublicUrl(banner) : null; - const avatarBlurhash = avatar ? avatar.blurhash : null; - const bannerBlurhash = banner ? banner.blurhash : null; await Users.update(user!.id, { avatarId, bannerId, - avatarUrl, - bannerUrl, - avatarBlurhash, - bannerBlurhash, }); user!.avatarId = avatarId; user!.bannerId = bannerId; - user!.avatarUrl = avatarUrl; - user!.bannerUrl = bannerUrl; - user!.avatarBlurhash = avatarBlurhash; - user!.bannerBlurhash = bannerBlurhash; //#endregion //#region カスタム絵文å—å–å¾— @@ -340,14 +328,10 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint if (avatar) { updates.avatarId = avatar.id; - updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); - updates.avatarBlurhash = avatar.blurhash; } if (banner) { updates.bannerId = banner.id; - updates.bannerUrl = DriveFiles.getPublicUrl(banner); - updates.bannerBlurhash = banner.blurhash; } // Update user diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index 123c89ed78e1883a92ce5f3230d5914797a5e79a..6dc6abb00a1ee412b2f1f2ca3c8cbd7b6596131d 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -39,7 +39,6 @@ export const paramDef = { localDriveCapacityMb: { type: 'integer' }, remoteDriveCapacityMb: { type: 'integer' }, cacheRemoteFiles: { type: 'boolean' }, - proxyRemoteFiles: { type: 'boolean' }, emailRequiredForSignup: { type: 'boolean' }, enableHcaptcha: { type: 'boolean' }, hcaptchaSiteKey: { type: 'string', nullable: true }, @@ -175,10 +174,6 @@ export default define(meta, paramDef, async (ps, me) => { set.cacheRemoteFiles = ps.cacheRemoteFiles; } - if (ps.proxyRemoteFiles !== undefined) { - set.proxyRemoteFiles = ps.proxyRemoteFiles; - } - if (ps.emailRequiredForSignup !== undefined) { set.emailRequiredForSignup = ps.emailRequiredForSignup; } diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts index 7b1b20668ec6381fe3bf0691e65677b57d5bf18f..f0cb2ba3c0476c629687c85e790b0cabd9c06a93 100644 --- a/packages/backend/src/server/api/endpoints/antennas/notes.ts +++ b/packages/backend/src/server/api/endpoints/antennas/notes.ts @@ -65,10 +65,16 @@ export default define(meta, paramDef, async (ps, user) => { ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere(`note.id IN (${ antennaQuery.getQuery() })`) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') .setParameters(antennaQuery.getParameters()); generateVisibilityQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts index b57468d04723688d04db53c6c88bcb6843c25dbe..57a9fa44b86138679dde999a9c56547900180eae 100644 --- a/packages/backend/src/server/api/endpoints/channels/timeline.ts +++ b/packages/backend/src/server/api/endpoints/channels/timeline.ts @@ -55,10 +55,16 @@ export default define(meta, paramDef, async (ps, user) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.channelId = :channelId', { channelId: channel.id }) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') .leftJoinAndSelect('note.channel', 'channel'); //#endregion diff --git a/packages/backend/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts index 0f0eac4c4b87ab4d6b2a74b82aa2c245761bd6b5..2627884ee16317ff6dee32884c1c47768f4ca32b 100644 --- a/packages/backend/src/server/api/endpoints/clips/notes.ts +++ b/packages/backend/src/server/api/endpoints/clips/notes.ts @@ -64,10 +64,16 @@ export default define(meta, paramDef, async (ps, user) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) .andWhere(`note.id IN (${ clipQuery.getQuery() })`) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') .setParameters(clipQuery.getParameters()); if (user) { diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts index c6291211e47edfb844aca1a85b191e356d6f8101..7d9bd44d1d1b71fa33e2af44f4fb6b7c544ac4f4 100644 --- a/packages/backend/src/server/api/endpoints/i/notifications.ts +++ b/packages/backend/src/server/api/endpoints/i/notifications.ts @@ -71,10 +71,16 @@ export default define(meta, paramDef, async (ps, user) => { .leftJoinAndSelect('notification.notifier', 'notifier') .leftJoinAndSelect('notification.note', 'note') .leftJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); query.andWhere(new Brackets(qb => { qb .where(`notification.notifierId NOT IN (${ mutingQuery.getQuery() })`) diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index d8dff4f49fdda5fc68bff633070e191af4b0facb..85d0a62548f9bdc40ba61e98298ada1628561975 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -175,12 +175,6 @@ export default define(meta, paramDef, async (ps, _user, token) => { if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage); - - updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); - - if (avatar.blurhash) { - updates.avatarBlurhash = avatar.blurhash; - } } if (ps.bannerId) { @@ -188,12 +182,6 @@ export default define(meta, paramDef, async (ps, _user, token) => { if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage); - - updates.bannerUrl = DriveFiles.getPublicUrl(banner, false); - - if (banner.blurhash) { - updates.bannerBlurhash = banner.blurhash; - } } if (ps.pinnedPageId) { diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index df959cbb725c8108cf76eb68e7942afc87bfa854..312b0757949b1d9574063879005b1e4481a41ed4 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -93,10 +93,6 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, - proxyRemoteFiles: { - type: 'boolean', - optional: false, nullable: false, - }, emailRequiredForSignup: { type: 'boolean', optional: false, nullable: false, @@ -529,7 +525,6 @@ export default define(meta, paramDef, async (ps, me) => { pinnedPages: instance.pinnedPages, pinnedClipId: instance.pinnedClipId, cacheRemoteFiles: instance.cacheRemoteFiles, - proxyRemoteFiles: instance.proxyRemoteFiles, requireSetup: (await Users.count({ host: null, })) === 0, diff --git a/packages/backend/src/server/api/endpoints/notes.ts b/packages/backend/src/server/api/endpoints/notes.ts index 07862a7bfbfc73d658f3ca9056dbf0eef1aa6c6a..96657f8d3f29a6897a9714820959f8b827763d54 100644 --- a/packages/backend/src/server/api/endpoints/notes.ts +++ b/packages/backend/src/server/api/endpoints/notes.ts @@ -37,10 +37,16 @@ export default define(meta, paramDef, async (ps) => { .andWhere(`note.visibility = 'public'`) .andWhere(`note.localOnly = FALSE`) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); if (ps.local) { query.andWhere('note.userHost IS NULL'); diff --git a/packages/backend/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts index 38f2c12d2dd76e1e3453e6c62f1800100a45d667..86dde30d648d261714ddd12d56d3c9e28700c1e1 100644 --- a/packages/backend/src/server/api/endpoints/notes/children.ts +++ b/packages/backend/src/server/api/endpoints/notes/children.ts @@ -49,10 +49,16 @@ export default define(meta, paramDef, async (ps, user) => { })); })) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, user); if (user) generateMutedUserQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts index 913a4993145a37a786df98f14c9fcf838a80d9ad..6308d23696a7f8ca325f16574a74132bca824128 100644 --- a/packages/backend/src/server/api/endpoints/notes/featured.ts +++ b/packages/backend/src/server/api/endpoints/notes/featured.ts @@ -40,10 +40,16 @@ export default define(meta, paramDef, async (ps, user) => { .andWhere(`note.createdAt > :date`, { date: new Date(Date.now() - day) }) .andWhere(`note.visibility = 'public'`) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); if (user) generateMutedUserQuery(query, user); if (user) generateBlockedUserQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts index a5cd5de63efef2284a02358368a04aa9008a30f9..26aaa0919c1ce74ebad3f720222483bffe807654 100644 --- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts @@ -60,10 +60,16 @@ export default define(meta, paramDef, async (ps, user) => { .andWhere('note.visibility = \'public\'') .andWhere('note.channelId IS NULL') .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateRepliesQuery(query, user); if (user) generateMutedUserQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts index 96e9b5d0e7e65c1f0835508ead83a5ee5149d62c..9bcb64b6565d92c29af8eeaa92e97e7a7b50c2c6 100644 --- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -72,10 +72,16 @@ export default define(meta, paramDef, async (ps, user) => { .orWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)'); })) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') .setParameters(followingQuery.getParameters()); generateChannelQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts index 5f21f0e238ca674b2b7844810b1adb90cb50db11..12fc88b1fd4b35018f5aaf57fdf53c385f81b993 100644 --- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts @@ -65,10 +65,16 @@ export default define(meta, paramDef, async (ps, user) => { ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)') .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateChannelQuery(query, user); generateRepliesQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts index 269eaa932420285b32eb2684005dfd7435224df1..eafbba322dfaf1a805a6f7aca5c27217d8f82111 100644 --- a/packages/backend/src/server/api/endpoints/notes/mentions.ts +++ b/packages/backend/src/server/api/endpoints/notes/mentions.ts @@ -48,10 +48,16 @@ export default define(meta, paramDef, async (ps, user) => { .orWhere(`'{"${user.id}"}' <@ note.visibleUserIds`); })) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, user); generateMutedUserQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/reactions.ts b/packages/backend/src/server/api/endpoints/notes/reactions.ts index 629cf014bb9d1438fa7d31eae6dc5b5791a1353a..43e5d1ef6fc0fc166ffc566dc2f035d90595cffa 100644 --- a/packages/backend/src/server/api/endpoints/notes/reactions.ts +++ b/packages/backend/src/server/api/endpoints/notes/reactions.ts @@ -68,6 +68,7 @@ export default define(meta, paramDef, async (ps, user) => { order: { id: -1, }, + relations: ['user', 'user.avatar', 'user.banner', 'note'], }); return await Promise.all(reactions.map(reaction => NoteReactions.pack(reaction, user))); diff --git a/packages/backend/src/server/api/endpoints/notes/renotes.ts b/packages/backend/src/server/api/endpoints/notes/renotes.ts index 52440f8a6109bfaadf41e111a81b9282e96041c4..87c855a5e8f94f983995dafc5d4ec3ead4cc7d81 100644 --- a/packages/backend/src/server/api/endpoints/notes/renotes.ts +++ b/packages/backend/src/server/api/endpoints/notes/renotes.ts @@ -52,10 +52,16 @@ export default define(meta, paramDef, async (ps, user) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) .andWhere(`note.renoteId = :renoteId`, { renoteId: note.id }) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, user); if (user) generateMutedUserQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/replies.ts b/packages/backend/src/server/api/endpoints/notes/replies.ts index 10b33ea8c9e10d277c3b49c8e80f5bc0dd97659d..3053eabe33a112dc195aef809be1a9fc2e91d88d 100644 --- a/packages/backend/src/server/api/endpoints/notes/replies.ts +++ b/packages/backend/src/server/api/endpoints/notes/replies.ts @@ -37,10 +37,16 @@ export default define(meta, paramDef, async (ps, user) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) .andWhere('note.replyId = :replyId', { replyId: ps.noteId }) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, user); if (user) generateMutedUserQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts index 94fb344c08aefd9044579a3b96a0664fcfc92f4a..c6503eb0570e9ac7ce4b63fc71bf3c96091acc8d 100644 --- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts +++ b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts @@ -46,10 +46,16 @@ export const paramDef = { export default define(meta, paramDef, async (ps, me) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, me); if (me) generateMutedUserQuery(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts index 1295542efd364d3af32ffd03bbffb771c83633d5..e77892b150099a08eed9bd31c4291d185d137dde 100644 --- a/packages/backend/src/server/api/endpoints/notes/search.ts +++ b/packages/backend/src/server/api/endpoints/notes/search.ts @@ -56,10 +56,16 @@ export default define(meta, paramDef, async (ps, me) => { query .andWhere('note.text ILIKE :q', { q: `%${ps.query}%` }) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, me); if (me) generateMutedUserQuery(query, me); diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts index 416e507e9bd62b0f99b89963d8b764cee8a400c1..fde66b241b93cc0c2c6aaa7b6044d44a73292832 100644 --- a/packages/backend/src/server/api/endpoints/notes/timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/timeline.ts @@ -64,10 +64,16 @@ export default define(meta, paramDef, async (ps, user) => { if (hasFollowing) qb.orWhere(`note.userId IN (${ followingQuery.getQuery() })`); })) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') .setParameters(followingQuery.getParameters()); generateChannelQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts index 990c09f07ca7f58b4661a42f653d39df32b49366..0829d0e4c1e4d2d0a3f76cf87e7d3e81df2bbbe3 100644 --- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts +++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts @@ -66,10 +66,16 @@ export default define(meta, paramDef, async (ps, user) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) .andWhere(`note.userId IN (${ listQuery.getQuery() })`) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner') .setParameters(listQuery.getParameters()); generateVisibilityQuery(query, user); diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts index 1f61773c44e29753581167eddd20a728a21d7a52..16318d222536e5bd451664f95852fc7088b04b4e 100644 --- a/packages/backend/src/server/api/endpoints/users/notes.ts +++ b/packages/backend/src/server/api/endpoints/users/notes.ts @@ -63,10 +63,16 @@ export default define(meta, paramDef, async (ps, me) => { const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.userId = :userId', { userId: user.id }) .innerJoinAndSelect('note.user', 'user') + .leftJoinAndSelect('user.avatar', 'avatar') + .leftJoinAndSelect('user.banner', 'banner') .leftJoinAndSelect('note.reply', 'reply') .leftJoinAndSelect('note.renote', 'renote') .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); + .leftJoinAndSelect('replyUser.avatar', 'replyUserAvatar') + .leftJoinAndSelect('replyUser.banner', 'replyUserBanner') + .leftJoinAndSelect('renote.user', 'renoteUser') + .leftJoinAndSelect('renoteUser.avatar', 'renoteUserAvatar') + .leftJoinAndSelect('renoteUser.banner', 'renoteUserBanner'); generateVisibilityQuery(query, me); if (me) generateMutedUserQuery(query, me, user); diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts index a448925b682daef549df80a81e39bd25d1dfba6c..80130e88438f5dff050239fcbbe78e1ed8eb1338 100644 --- a/packages/backend/src/server/index.ts +++ b/packages/backend/src/server/index.ts @@ -76,6 +76,8 @@ router.get('/avatar/@:acct', async ctx => { usernameLower: username.toLowerCase(), host: host === config.host ? null : host, isSuspended: false, + }, { + relations: ['avatar'], }); if (user) { diff --git a/packages/client/src/pages/admin/settings.vue b/packages/client/src/pages/admin/settings.vue index 17f7842ab23dca555ed7e8b9ae310101997dd7d0..5cf4d6c882faf4b77ce3485797363a803fea547a 100644 --- a/packages/client/src/pages/admin/settings.vue +++ b/packages/client/src/pages/admin/settings.vue @@ -76,11 +76,6 @@ <template #caption>{{ $ts.cacheRemoteFilesDescription }}</template> </FormSwitch> - <FormSwitch v-model="proxyRemoteFiles" class="_formBlock"> - <template #label>{{ $ts.proxyRemoteFiles }}</template> - <template #caption>{{ $ts.proxyRemoteFilesDescription }}</template> - </FormSwitch> - <FormSplit :min-width="280"> <FormInput v-model="localDriveCapacityMb" type="number" class="_formBlock"> <template #label>{{ $ts.driveCapacityPerLocalAccount }}</template> @@ -185,7 +180,6 @@ export default defineComponent({ enableGlobalTimeline: false, pinnedUsers: '', cacheRemoteFiles: false, - proxyRemoteFiles: false, localDriveCapacityMb: 0, remoteDriveCapacityMb: 0, enableRegistration: false, @@ -214,7 +208,6 @@ export default defineComponent({ this.enableGlobalTimeline = !meta.disableGlobalTimeline; this.pinnedUsers = meta.pinnedUsers.join('\n'); this.cacheRemoteFiles = meta.cacheRemoteFiles; - this.proxyRemoteFiles = meta.proxyRemoteFiles; this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb; this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb; this.enableRegistration = !meta.disableRegistration; @@ -241,7 +234,6 @@ export default defineComponent({ disableGlobalTimeline: !this.enableGlobalTimeline, pinnedUsers: this.pinnedUsers.split('\n'), cacheRemoteFiles: this.cacheRemoteFiles, - proxyRemoteFiles: this.proxyRemoteFiles, localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10), remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10), disableRegistration: !this.enableRegistration,