Fix avatar/banner proxy
This commit is contained in:
		
							parent
							
								
									da20675ada
								
							
						
					
					
						commit
						c43a2ce7be
					
				
					 13 changed files with 46 additions and 88 deletions
				
			
		|  | @ -155,6 +155,9 @@ id: 'aid' | ||||||
| # Media Proxy | # Media Proxy | ||||||
| #mediaProxy: https://example.com/proxy | #mediaProxy: https://example.com/proxy | ||||||
| 
 | 
 | ||||||
|  | # Proxy remote files (default: false) | ||||||
|  | #proxyRemoteFiles: true | ||||||
|  | 
 | ||||||
| # Sign to ActivityPub GET request (default: false) | # Sign to ActivityPub GET request (default: false) | ||||||
| #signToActivityPubGet: true | #signToActivityPubGet: true | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -320,8 +320,6 @@ disablingTimelinesInfo: "これらのタイムラインを無効化しても、 | ||||||
| registration: "登録" | registration: "登録" | ||||||
| enableRegistration: "誰でも新規登録できるようにする" | enableRegistration: "誰でも新規登録できるようにする" | ||||||
| invite: "招待" | invite: "招待" | ||||||
| proxyRemoteFiles: "リモートのファイルをプロキシする" |  | ||||||
| proxyRemoteFilesDescription: "この設定を有効にすると、未保存または保存容量超過で削除されたリモートファイルをローカルでプロキシし、サムネイルも生成するようになります。サーバーのストレージには影響しません、" |  | ||||||
| driveCapacityPerLocalAccount: "ローカルユーザーひとりあたりのドライブ容量" | driveCapacityPerLocalAccount: "ローカルユーザーひとりあたりのドライブ容量" | ||||||
| driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのドライブ容量" | driveCapacityPerRemoteAccount: "リモートユーザーひとりあたりのドライブ容量" | ||||||
| inMb: "メガバイト単位" | inMb: "メガバイト単位" | ||||||
|  |  | ||||||
							
								
								
									
										21
									
								
								migration/1626509500668-fix-remote-file-proxy.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								migration/1626509500668-fix-remote-file-proxy.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | import {MigrationInterface, QueryRunner} from "typeorm"; | ||||||
|  | 
 | ||||||
|  | export class fixRemoteFileProxy1626509500668 implements MigrationInterface { | ||||||
|  |     name = 'fixRemoteFileProxy1626509500668' | ||||||
|  | 
 | ||||||
|  |     public async up(queryRunner: QueryRunner): Promise<void> { | ||||||
|  |         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"`); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public async down(queryRunner: QueryRunner): Promise<void> { | ||||||
|  |         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)`); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -6,11 +6,6 @@ | ||||||
| 			<template #desc>{{ $ts.cacheRemoteFilesDescription }}</template> | 			<template #desc>{{ $ts.cacheRemoteFilesDescription }}</template> | ||||||
| 		</FormSwitch> | 		</FormSwitch> | ||||||
| 
 | 
 | ||||||
| 		<FormSwitch v-model:value="proxyRemoteFiles"> |  | ||||||
| 			{{ $ts.proxyRemoteFiles }} |  | ||||||
| 			<template #desc>{{ $ts.proxyRemoteFilesDescription }}</template> |  | ||||||
| 		</FormSwitch> |  | ||||||
| 
 |  | ||||||
| 		<FormInput v-model:value="localDriveCapacityMb" type="number"> | 		<FormInput v-model:value="localDriveCapacityMb" type="number"> | ||||||
| 			<span>{{ $ts.driveCapacityPerLocalAccount }}</span> | 			<span>{{ $ts.driveCapacityPerLocalAccount }}</span> | ||||||
| 			<template #suffix>MB</template> | 			<template #suffix>MB</template> | ||||||
|  | @ -59,7 +54,6 @@ export default defineComponent({ | ||||||
| 				icon: 'fas fa-cloud' | 				icon: 'fas fa-cloud' | ||||||
| 			}, | 			}, | ||||||
| 			cacheRemoteFiles: false, | 			cacheRemoteFiles: false, | ||||||
| 			proxyRemoteFiles: false, |  | ||||||
| 			localDriveCapacityMb: 0, | 			localDriveCapacityMb: 0, | ||||||
| 			remoteDriveCapacityMb: 0, | 			remoteDriveCapacityMb: 0, | ||||||
| 		} | 		} | ||||||
|  | @ -73,14 +67,12 @@ export default defineComponent({ | ||||||
| 		async init() { | 		async init() { | ||||||
| 			const meta = await os.api('meta', { detail: true }); | 			const meta = await os.api('meta', { detail: true }); | ||||||
| 			this.cacheRemoteFiles = meta.cacheRemoteFiles; | 			this.cacheRemoteFiles = meta.cacheRemoteFiles; | ||||||
| 			this.proxyRemoteFiles = meta.proxyRemoteFiles; |  | ||||||
| 			this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb; | 			this.localDriveCapacityMb = meta.driveCapacityPerLocalUserMb; | ||||||
| 			this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb; | 			this.remoteDriveCapacityMb = meta.driveCapacityPerRemoteUserMb; | ||||||
| 		}, | 		}, | ||||||
| 		save() { | 		save() { | ||||||
| 			os.apiWithDialog('admin/update-meta', { | 			os.apiWithDialog('admin/update-meta', { | ||||||
| 				cacheRemoteFiles: this.cacheRemoteFiles, | 				cacheRemoteFiles: this.cacheRemoteFiles, | ||||||
| 				proxyRemoteFiles: this.proxyRemoteFiles, |  | ||||||
| 				localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10), | 				localDriveCapacityMb: parseInt(this.localDriveCapacityMb, 10), | ||||||
| 				remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10), | 				remoteDriveCapacityMb: parseInt(this.remoteDriveCapacityMb, 10), | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
|  |  | ||||||
|  | @ -60,6 +60,7 @@ export type Source = { | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	mediaProxy?: string; | 	mediaProxy?: string; | ||||||
|  | 	proxyRemoteFiles?: boolean; | ||||||
| 
 | 
 | ||||||
| 	signToActivityPubGet?: boolean; | 	signToActivityPubGet?: boolean; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -131,11 +131,6 @@ export class Meta { | ||||||
| 	}) | 	}) | ||||||
| 	public cacheRemoteFiles: boolean; | 	public cacheRemoteFiles: boolean; | ||||||
| 
 | 
 | ||||||
| 	@Column('boolean', { |  | ||||||
| 		default: false, |  | ||||||
| 	}) |  | ||||||
| 	public proxyRemoteFiles: boolean; |  | ||||||
| 
 |  | ||||||
| 	@Column({ | 	@Column({ | ||||||
| 		...id(), | 		...id(), | ||||||
| 		nullable: true, | 		nullable: true, | ||||||
|  |  | ||||||
|  | @ -106,26 +106,6 @@ export class User { | ||||||
| 	}) | 	}) | ||||||
| 	public tags: string[]; | 	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', { | 	@Column('boolean', { | ||||||
| 		default: false, | 		default: false, | ||||||
| 		comment: 'Whether the User is suspended.' | 		comment: 'Whether the User is suspended.' | ||||||
|  |  | ||||||
|  | @ -30,7 +30,7 @@ export class DriveFileRepository extends Repository<DriveFile> { | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	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) { | 		if (file.uri != null && file.userHost != null && config.mediaProxy != null) { | ||||||
| 			return appendQuery(config.mediaProxy, query({ | 			return appendQuery(config.mediaProxy, query({ | ||||||
|  | @ -40,7 +40,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; | 			const key = thumbnail ? file.thumbnailAccessKey : file.webpublicAccessKey; | ||||||
| 
 | 
 | ||||||
| 			if (key && !key.match('/')) {	// 古いものはここにオブジェクトストレージキーが入ってるので除外
 | 			if (key && !key.match('/')) {	// 古いものはここにオブジェクトストレージキーが入ってるので除外
 | ||||||
|  | @ -113,8 +113,6 @@ export class DriveFileRepository extends Repository<DriveFile> { | ||||||
| 		const file = typeof src === 'object' ? src : await this.findOne(src); | 		const file = typeof src === 'object' ? src : await this.findOne(src); | ||||||
| 		if (file == null) return null; | 		if (file == null) return null; | ||||||
| 
 | 
 | ||||||
| 		const meta = await fetchMeta(); |  | ||||||
| 
 |  | ||||||
| 		return await awaitAll({ | 		return await awaitAll({ | ||||||
| 			id: file.id, | 			id: file.id, | ||||||
| 			createdAt: file.createdAt.toISOString(), | 			createdAt: file.createdAt.toISOString(), | ||||||
|  | @ -125,8 +123,8 @@ export class DriveFileRepository extends Repository<DriveFile> { | ||||||
| 			isSensitive: file.isSensitive, | 			isSensitive: file.isSensitive, | ||||||
| 			blurhash: file.blurhash, | 			blurhash: file.blurhash, | ||||||
| 			properties: file.properties, | 			properties: file.properties, | ||||||
| 			url: opts.self ? file.url : this.getPublicUrl(file, false, meta), | 			url: opts.self ? file.url : this.getPublicUrl(file, false), | ||||||
| 			thumbnailUrl: this.getPublicUrl(file, true, meta), | 			thumbnailUrl: this.getPublicUrl(file, true), | ||||||
| 			comment: file.comment, | 			comment: file.comment, | ||||||
| 			folderId: file.folderId, | 			folderId: file.folderId, | ||||||
| 			folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, { | 			folder: opts.detail && file.folderId ? DriveFolders.pack(file.folderId, { | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import $ from 'cafy'; | import $ from 'cafy'; | ||||||
| import { EntityRepository, Repository, In, Not } from 'typeorm'; | import { EntityRepository, Repository, In, Not } from 'typeorm'; | ||||||
| import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; | import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; | ||||||
| import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances } from '../index'; | import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index'; | ||||||
| import config from '@/config/index'; | import config from '@/config/index'; | ||||||
| import { SchemaType } from '@/misc/schema'; | import { SchemaType } from '@/misc/schema'; | ||||||
| import { awaitAll } from '@/prelude/await-all'; | import { awaitAll } from '@/prelude/await-all'; | ||||||
|  | @ -170,7 +170,18 @@ export class UserRepository extends Repository<User> { | ||||||
| 			includeSecrets: false | 			includeSecrets: false | ||||||
| 		}, options); | 		}, 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 meId = me ? me.id : null; | ||||||
| 
 | 
 | ||||||
| 		const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; | 		const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null; | ||||||
|  | @ -188,8 +199,8 @@ export class UserRepository extends Repository<User> { | ||||||
| 			name: user.name, | 			name: user.name, | ||||||
| 			username: user.username, | 			username: user.username, | ||||||
| 			host: user.host, | 			host: user.host, | ||||||
| 			avatarUrl: user.avatarUrl ? user.avatarUrl : config.url + '/avatar/' + user.id, | 			avatarUrl: user.avatar ? DriveFiles.getPublicUrl(user.avatar, true) : config.url + '/avatar/' + user.id, | ||||||
| 			avatarBlurhash: user.avatarBlurhash, | 			avatarBlurhash: user.avatar?.blurhash || null, | ||||||
| 			avatarColor: null, // 後方互換性のため
 | 			avatarColor: null, // 後方互換性のため
 | ||||||
| 			isAdmin: user.isAdmin || falsy, | 			isAdmin: user.isAdmin || falsy, | ||||||
| 			isModerator: user.isModerator || falsy, | 			isModerator: user.isModerator || falsy, | ||||||
|  | @ -212,8 +223,8 @@ export class UserRepository extends Repository<User> { | ||||||
| 				createdAt: user.createdAt.toISOString(), | 				createdAt: user.createdAt.toISOString(), | ||||||
| 				updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, | 				updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null, | ||||||
| 				lastFetchedAt: user.lastFetchedAt?.toISOString(), | 				lastFetchedAt: user.lastFetchedAt?.toISOString(), | ||||||
| 				bannerUrl: user.bannerUrl, | 				bannerUrl: user.banner ? DriveFiles.getPublicUrl(user.banner, false) : null, | ||||||
| 				bannerBlurhash: user.bannerBlurhash, | 				bannerBlurhash: user.banner?.blurhash || null, | ||||||
| 				bannerColor: null, // 後方互換性のため
 | 				bannerColor: null, // 後方互換性のため
 | ||||||
| 				isLocked: user.isLocked, | 				isLocked: user.isLocked, | ||||||
| 				isModerator: user.isModerator || falsy, | 				isModerator: user.isModerator || falsy, | ||||||
|  |  | ||||||
|  | @ -231,26 +231,14 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us | ||||||
| 
 | 
 | ||||||
| 	const avatarId = avatar ? avatar.id : null; | 	const avatarId = avatar ? avatar.id : null; | ||||||
| 	const bannerId = banner ? banner.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, { | 	await Users.update(user!.id, { | ||||||
| 		avatarId, | 		avatarId, | ||||||
| 		bannerId, | 		bannerId, | ||||||
| 		avatarUrl, |  | ||||||
| 		bannerUrl, |  | ||||||
| 		avatarBlurhash, |  | ||||||
| 		bannerBlurhash |  | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	user!.avatarId = avatarId; | 	user!.avatarId = avatarId; | ||||||
| 	user!.bannerId = bannerId; | 	user!.bannerId = bannerId; | ||||||
| 	user!.avatarUrl = avatarUrl; |  | ||||||
| 	user!.bannerUrl = bannerUrl; |  | ||||||
| 	user!.avatarBlurhash = avatarBlurhash; |  | ||||||
| 	user!.bannerBlurhash = bannerBlurhash; |  | ||||||
| 	//#endregion
 | 	//#endregion
 | ||||||
| 
 | 
 | ||||||
| 	//#region カスタム絵文字取得
 | 	//#region カスタム絵文字取得
 | ||||||
|  | @ -343,14 +331,10 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint | ||||||
| 
 | 
 | ||||||
| 	if (avatar) { | 	if (avatar) { | ||||||
| 		updates.avatarId = avatar.id; | 		updates.avatarId = avatar.id; | ||||||
| 		updates.avatarUrl = DriveFiles.getPublicUrl(avatar, true); |  | ||||||
| 		updates.avatarBlurhash = avatar.blurhash; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (banner) { | 	if (banner) { | ||||||
| 		updates.bannerId = banner.id; | 		updates.bannerId = banner.id; | ||||||
| 		updates.bannerUrl = DriveFiles.getPublicUrl(banner); |  | ||||||
| 		updates.bannerBlurhash = banner.blurhash; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Update user
 | 	// Update user
 | ||||||
|  |  | ||||||
|  | @ -89,10 +89,6 @@ export const meta = { | ||||||
| 			validator: $.optional.bool, | 			validator: $.optional.bool, | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		proxyRemoteFiles: { |  | ||||||
| 			validator: $.optional.bool, |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		enableHcaptcha: { | 		enableHcaptcha: { | ||||||
| 			validator: $.optional.bool, | 			validator: $.optional.bool, | ||||||
| 		}, | 		}, | ||||||
|  | @ -370,10 +366,6 @@ export default define(meta, async (ps, me) => { | ||||||
| 		set.cacheRemoteFiles = ps.cacheRemoteFiles; | 		set.cacheRemoteFiles = ps.cacheRemoteFiles; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (ps.proxyRemoteFiles !== undefined) { |  | ||||||
| 		set.proxyRemoteFiles = ps.proxyRemoteFiles; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (ps.enableHcaptcha !== undefined) { | 	if (ps.enableHcaptcha !== undefined) { | ||||||
| 		set.enableHcaptcha = ps.enableHcaptcha; | 		set.enableHcaptcha = ps.enableHcaptcha; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -195,12 +195,6 @@ export default define(meta, async (ps, _user, token) => { | ||||||
| 
 | 
 | ||||||
| 		if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); | 		if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); | ||||||
| 		if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage); | 		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) { | 	if (ps.bannerId) { | ||||||
|  | @ -208,12 +202,6 @@ export default define(meta, async (ps, _user, token) => { | ||||||
| 
 | 
 | ||||||
| 		if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); | 		if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); | ||||||
| 		if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage); | 		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) { | 	if (ps.pinnedPageId) { | ||||||
|  |  | ||||||
|  | @ -100,10 +100,6 @@ export const meta = { | ||||||
| 				type: 'boolean' as const, | 				type: 'boolean' as const, | ||||||
| 				optional: false as const, nullable: false as const | 				optional: false as const, nullable: false as const | ||||||
| 			}, | 			}, | ||||||
| 			proxyRemoteFiles: { |  | ||||||
| 				type: 'boolean' as const, |  | ||||||
| 				optional: false as const, nullable: false as const |  | ||||||
| 			}, |  | ||||||
| 			enableHcaptcha: { | 			enableHcaptcha: { | ||||||
| 				type: 'boolean' as const, | 				type: 'boolean' as const, | ||||||
| 				optional: false as const, nullable: false as const | 				optional: false as const, nullable: false as const | ||||||
|  | @ -522,7 +518,6 @@ export default define(meta, async (ps, me) => { | ||||||
| 			pinnedPages: instance.pinnedPages, | 			pinnedPages: instance.pinnedPages, | ||||||
| 			pinnedClipId: instance.pinnedClipId, | 			pinnedClipId: instance.pinnedClipId, | ||||||
| 			cacheRemoteFiles: instance.cacheRemoteFiles, | 			cacheRemoteFiles: instance.cacheRemoteFiles, | ||||||
| 			proxyRemoteFiles: instance.proxyRemoteFiles, |  | ||||||
| 			requireSetup: (await Users.count({ | 			requireSetup: (await Users.count({ | ||||||
| 				host: null, | 				host: null, | ||||||
| 			})) === 0, | 			})) === 0, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue