Compare commits
	
		
			No commits in common. "ec229dbd3b50fdb644dd9e6903e0544be21e55f1" and "db5046ed3a6b156094f2863b3941854865c25214" have entirely different histories.
		
	
	
		
			ec229dbd3b
			...
			db5046ed3a
		
	
		|  | @ -25,13 +25,9 @@ | ||||||
| - Enhance: 自分が押したリアクションのデザインを改善 | - Enhance: 自分が押したリアクションのデザインを改善 | ||||||
| - Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 | - Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 | ||||||
| - Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 | - Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 | ||||||
| - Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正 |  | ||||||
| 
 | 
 | ||||||
| ### Server | ### Server | ||||||
| - cacheRemoteFilesの初期値はfalseになりました | - cacheRemoteFilesの初期値はfalseになりました | ||||||
| - 一部のfeatured noteを照会できない問題を修正 |  | ||||||
| - ファイルアップロード時等にファイル名の拡張子を修正する関数(correctFilename)の挙動を改善 |  | ||||||
| - fix: muteがapiからのuser list timeline取得で機能しない問題を修正 |  | ||||||
| 
 | 
 | ||||||
| ## 13.14.2 | ## 13.14.2 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -131,13 +131,13 @@ export class ApNoteService { | ||||||
| 		this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); | 		this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); | ||||||
| 
 | 
 | ||||||
| 		if (note.id && !checkHttps(note.id)) { | 		if (note.id && !checkHttps(note.id)) { | ||||||
| 			throw new Error('unexpected schema of note.id: ' + note.id); | 			throw new Error('unexpected shcema of note.id: ' + note.id); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		const url = getOneApHrefNullable(note.url); | 		const url = getOneApHrefNullable(note.url); | ||||||
| 
 | 
 | ||||||
| 		if (url && !checkHttps(url)) { | 		if (url && !checkHttps(url)) { | ||||||
| 			throw new Error('unexpected schema of note url: ' + url); | 			throw new Error('unexpected shcema of note url: ' + url); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		this.logger.info(`Creating the Note: ${note.id}`); | 		this.logger.info(`Creating the Note: ${note.id}`); | ||||||
|  | @ -271,7 +271,6 @@ export class ApNoteService { | ||||||
| 
 | 
 | ||||||
| 		const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined); | 		const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined); | ||||||
| 
 | 
 | ||||||
| 		try { |  | ||||||
| 		return await this.noteCreateService.create(actor, { | 		return await this.noteCreateService.create(actor, { | ||||||
| 			createdAt: note.published ? new Date(note.published) : null, | 			createdAt: note.published ? new Date(note.published) : null, | ||||||
| 			files, | 			files, | ||||||
|  | @ -290,17 +289,6 @@ export class ApNoteService { | ||||||
| 			uri: note.id, | 			uri: note.id, | ||||||
| 			url: url, | 			url: url, | ||||||
| 		}, silent); | 		}, silent); | ||||||
| 		} catch (err: any) { |  | ||||||
| 			if (err.name !== 'duplicated') { |  | ||||||
| 				throw err; |  | ||||||
| 			} |  | ||||||
| 			this.logger.info('The note is already inserted while creating itself, reading again'); |  | ||||||
| 			const duplicate = await this.fetchNote(value); |  | ||||||
| 			if (!duplicate) { |  | ||||||
| 				throw new Error('The note creation failed with duplication error even when there is no duplication'); |  | ||||||
| 			} |  | ||||||
| 			return duplicate; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  |  | ||||||
|  | @ -3,54 +3,18 @@ | ||||||
|  * SPDX-License-Identifier: AGPL-3.0-only |  * SPDX-License-Identifier: AGPL-3.0-only | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /** | // 与えられた拡張子とファイル名が一致しているかどうかを確認し、
 | ||||||
|  * Array.includes()よりSet.has()の方が高速 | // 一致していない場合は拡張子を付与して返す
 | ||||||
|  */ |  | ||||||
| const targetExtsToSkip = new Set([ |  | ||||||
| 	'.gz', |  | ||||||
| 	'.tar', |  | ||||||
| 	'.tgz', |  | ||||||
| 	'.bz2', |  | ||||||
| 	'.xz', |  | ||||||
| 	'.zip', |  | ||||||
| 	'.7z', |  | ||||||
| ]); |  | ||||||
| 
 |  | ||||||
| const extRegExp = /\.[0-9a-zA-Z]+$/i; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 与えられた拡張子とファイル名が一致しているかどうかを確認し、 |  | ||||||
|  * 一致していない場合は拡張子を付与して返す |  | ||||||
|  *  |  | ||||||
|  * extはfile-typeのextを想定 |  | ||||||
|  */ |  | ||||||
| export function correctFilename(filename: string, ext: string | null) { | export function correctFilename(filename: string, ext: string | null) { | ||||||
| 	const dotExt = ext ? ext[0] === '.' ? ext : `.${ext}` : '.unknown'; | 	const dotExt = ext ? ext.startsWith('.') ? ext : `.${ext}` : '.unknown'; | ||||||
| 
 | 	if (filename.endsWith(dotExt)) { | ||||||
| 	const match = extRegExp.exec(filename); | 		return filename; | ||||||
| 	if (!match || !match[0]) { | 	} | ||||||
| 		// filenameが拡張子を持っていない場合は拡張子をつける
 | 	if (ext === 'jpg' && filename.endsWith('.jpeg')) { | ||||||
| 		return `${filename}${dotExt}`; | 		return filename; | ||||||
| 	} | 	} | ||||||
| 
 | 	if (ext === 'tif' && filename.endsWith('.tiff')) { | ||||||
| 	const filenameExt = match[0].toLowerCase(); |  | ||||||
| 	if ( |  | ||||||
| 		// 未知のファイル形式かつ拡張子がある場合は何もしない
 |  | ||||||
| 		ext === null || |  | ||||||
| 		// 拡張子が一致している場合は何もしない
 |  | ||||||
| 		filenameExt === dotExt || |  | ||||||
| 
 |  | ||||||
| 		// jpeg, tiffを同一視
 |  | ||||||
| 		dotExt === '.jpg' && filenameExt === '.jpeg' || |  | ||||||
| 		dotExt === '.tif' && filenameExt === '.tiff' || |  | ||||||
| 
 |  | ||||||
| 		// 圧縮形式っぽければ下手に拡張子を変えない
 |  | ||||||
| 		// https://github.com/misskey-dev/misskey/issues/11482
 |  | ||||||
| 		targetExtsToSkip.has(dotExt) |  | ||||||
| 	) { |  | ||||||
| 		return filename; | 		return filename; | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	// 拡張子があるが一致していないなどの場合は拡張子を付け足す
 |  | ||||||
| 	return `${filename}${dotExt}`; | 	return `${filename}${dotExt}`; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -96,10 +96,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | ||||||
| 				.andWhere('userListJoining.userListId = :userListId', { userListId: list.id }); | 				.andWhere('userListJoining.userListId = :userListId', { userListId: list.id }); | ||||||
| 
 | 
 | ||||||
| 			this.queryService.generateVisibilityQuery(query, me); | 			this.queryService.generateVisibilityQuery(query, me); | ||||||
| 			this.queryService.generateMutedUserQuery(query, me); |  | ||||||
| 			this.queryService.generateMutedNoteQuery(query, me); |  | ||||||
| 			this.queryService.generateBlockedUserQuery(query, me); |  | ||||||
| 			this.queryService.generateMutedUserRenotesQueryForNotes(query, me); |  | ||||||
| 
 | 
 | ||||||
| 			if (ps.includeMyRenotes === false) { | 			if (ps.includeMyRenotes === false) { | ||||||
| 				query.andWhere(new Brackets(qb => { | 				query.andWhere(new Brackets(qb => { | ||||||
|  |  | ||||||
|  | @ -259,21 +259,6 @@ describe('ActivityPub', () => { | ||||||
| 			assert.strictEqual(note.text, 'test test foo'); | 			assert.strictEqual(note.text, 'test test foo'); | ||||||
| 			assert.strictEqual(note.uri, actor2Note.id); | 			assert.strictEqual(note.uri, actor2Note.id); | ||||||
| 		}); | 		}); | ||||||
| 
 |  | ||||||
| 		test('Fetch a note that is a featured note of the attributed actor', async () => { |  | ||||||
| 			const actor = createRandomActor(); |  | ||||||
| 			actor.featured = `${actor.id}/collections/featured`; |  | ||||||
| 
 |  | ||||||
| 			const featured = createRandomFeaturedCollection(actor, 5); |  | ||||||
| 			const firstNote = (featured.items as NonTransientIPost[])[0]; |  | ||||||
| 
 |  | ||||||
| 			resolver.register(actor.id, actor); |  | ||||||
| 			resolver.register(actor.featured, featured); |  | ||||||
| 			resolver.register(firstNote.id, firstNote); |  | ||||||
| 
 |  | ||||||
| 			const note = await noteService.createNote(firstNote.id as string, resolver); |  | ||||||
| 			assert.strictEqual(note?.uri, firstNote.id); |  | ||||||
| 		}); |  | ||||||
| 	}); | 	}); | ||||||
| 
 | 
 | ||||||
| 	describe('Images', () => { | 	describe('Images', () => { | ||||||
|  |  | ||||||
|  | @ -1,48 +0,0 @@ | ||||||
| /* |  | ||||||
|  * SPDX-FileCopyrightText: syuilo and other misskey contributors |  | ||||||
|  * SPDX-License-Identifier: AGPL-3.0-only |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| import { correctFilename } from '@/misc/correct-filename.js'; |  | ||||||
| 
 |  | ||||||
| describe(correctFilename, () => { |  | ||||||
|     it('no ext to null', () => { |  | ||||||
|         expect(correctFilename('test', null)).toBe('test.unknown'); |  | ||||||
|     }); |  | ||||||
|     it('no ext to jpg', () => { |  | ||||||
|         expect(correctFilename('test', 'jpg')).toBe('test.jpg'); |  | ||||||
|     }); |  | ||||||
|     it('jpg to webp', () => { |  | ||||||
|         expect(correctFilename('test.jpg', 'webp')).toBe('test.jpg.webp'); |  | ||||||
|     }); |  | ||||||
|     it('jpg to .webp', () => { |  | ||||||
|         expect(correctFilename('test.jpg', '.webp')).toBe('test.jpg.webp'); |  | ||||||
|     }); |  | ||||||
|     it('jpeg to jpg', () => { |  | ||||||
|         expect(correctFilename('test.jpeg', 'jpg')).toBe('test.jpeg'); |  | ||||||
|     }); |  | ||||||
|     it('JPEG to jpg', () => { |  | ||||||
|         expect(correctFilename('test.JPEG', 'jpg')).toBe('test.JPEG'); |  | ||||||
|     }); |  | ||||||
|     it('jpg to jpg', () => { |  | ||||||
|         expect(correctFilename('test.jpg', 'jpg')).toBe('test.jpg'); |  | ||||||
|     }); |  | ||||||
|     it('JPG to jpg', () => { |  | ||||||
|         expect(correctFilename('test.JPG', 'jpg')).toBe('test.JPG'); |  | ||||||
|     }); |  | ||||||
|     it('tiff to tif', () => { |  | ||||||
|         expect(correctFilename('test.tiff', 'tif')).toBe('test.tiff'); |  | ||||||
|     }); |  | ||||||
|     it('skip gz', () => { |  | ||||||
|         expect(correctFilename('test.unitypackage', 'gz')).toBe('test.unitypackage'); |  | ||||||
|     }); |  | ||||||
|     it('skip text file', () => { |  | ||||||
|         expect(correctFilename('test.txt', null)).toBe('test.txt'); |  | ||||||
|     }); |  | ||||||
|     it('unknown', () => { |  | ||||||
|         expect(correctFilename('test.hoge', null)).toBe('test.hoge'); |  | ||||||
|     }); |  | ||||||
| 	test('non ascii with space', () => { |  | ||||||
| 		expect(correctFilename('ファイル 名前', 'jpg')).toBe('ファイル 名前.jpg'); |  | ||||||
| 	}); |  | ||||||
| }); |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| 
 | 
 | ||||||
| import { describe, test, expect } from '@jest/globals'; | import { describe, test, expect } from '@jest/globals'; | ||||||
| import { contentDisposition } from '@/misc/content-disposition.js'; | import { contentDisposition } from '@/misc/content-disposition.js'; | ||||||
|  | import { correctFilename } from '@/misc/correct-filename.js'; | ||||||
| 
 | 
 | ||||||
| describe('misc:content-disposition', () => { | describe('misc:content-disposition', () => { | ||||||
| 	test('inline', () => { | 	test('inline', () => { | ||||||
|  | @ -17,3 +18,30 @@ describe('misc:content-disposition', () => { | ||||||
| 		expect(contentDisposition('attachment', 'ファイル名')).toBe('attachment; filename=\"_____\"; filename*=UTF-8\'\'%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D'); | 		expect(contentDisposition('attachment', 'ファイル名')).toBe('attachment; filename=\"_____\"; filename*=UTF-8\'\'%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D'); | ||||||
| 	}); | 	}); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | describe('misc:correct-filename', () => { | ||||||
|  | 	test('simple', () => { | ||||||
|  | 		expect(correctFilename('filename', 'jpg')).toBe('filename.jpg'); | ||||||
|  | 	}); | ||||||
|  | 	test('with same ext', () => { | ||||||
|  | 		expect(correctFilename('filename.jpg', 'jpg')).toBe('filename.jpg'); | ||||||
|  | 	}); | ||||||
|  | 	test('.ext', () => { | ||||||
|  | 		expect(correctFilename('filename.jpg', '.jpg')).toBe('filename.jpg'); | ||||||
|  | 	}); | ||||||
|  | 	test('with different ext', () => { | ||||||
|  | 		expect(correctFilename('filename.webp', 'jpg')).toBe('filename.webp.jpg'); | ||||||
|  | 	}); | ||||||
|  | 	test('non ascii with space', () => { | ||||||
|  | 		expect(correctFilename('ファイル 名前', 'jpg')).toBe('ファイル 名前.jpg'); | ||||||
|  | 	}); | ||||||
|  | 	test('jpeg', () => { | ||||||
|  | 		expect(correctFilename('filename.jpeg', 'jpg')).toBe('filename.jpeg'); | ||||||
|  | 	}); | ||||||
|  | 	test('tiff', () => { | ||||||
|  | 		expect(correctFilename('filename.tiff', 'tif')).toBe('filename.tiff'); | ||||||
|  | 	}); | ||||||
|  | 	test('null ext', () => { | ||||||
|  | 		expect(correctFilename('filename', null)).toBe('filename.unknown'); | ||||||
|  | 	}); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | @ -40,7 +40,6 @@ html { | ||||||
| 	line-height: 1.35; | 	line-height: 1.35; | ||||||
| 	text-size-adjust: 100%; | 	text-size-adjust: 100%; | ||||||
| 	tab-size: 2; | 	tab-size: 2; | ||||||
| 	-webkit-text-size-adjust: 100%; |  | ||||||
| 
 | 
 | ||||||
| 	&, * { | 	&, * { | ||||||
| 		scrollbar-color: var(--scrollbarHandle) transparent; | 		scrollbar-color: var(--scrollbarHandle) transparent; | ||||||
|  |  | ||||||
|  | @ -358,7 +358,7 @@ importers: | ||||||
|         version: 2.1.0 |         version: 2.1.0 | ||||||
|       summaly: |       summaly: | ||||||
|         specifier: github:misskey-dev/summaly |         specifier: github:misskey-dev/summaly | ||||||
|         version: github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7 |         version: github.com/misskey-dev/summaly/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc | ||||||
|       systeminformation: |       systeminformation: | ||||||
|         specifier: 5.18.9 |         specifier: 5.18.9 | ||||||
|         version: 5.18.9 |         version: 5.18.9 | ||||||
|  | @ -997,7 +997,7 @@ importers: | ||||||
|         version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.0.27)(@storybook/components@7.1.0)(@storybook/core-events@7.0.27)(@storybook/manager-api@7.0.27)(@storybook/preview-api@7.0.27)(@storybook/theming@7.0.27)(@storybook/types@7.0.27)(react-dom@18.2.0)(react@18.2.0) |         version: github.com/misskey-dev/storybook-addon-misskey-theme/cf583db098365b2ccc81a82f63ca9c93bc32b640(@storybook/blocks@7.0.27)(@storybook/components@7.1.0)(@storybook/core-events@7.0.27)(@storybook/manager-api@7.0.27)(@storybook/preview-api@7.0.27)(@storybook/theming@7.0.27)(@storybook/types@7.0.27)(react-dom@18.2.0)(react@18.2.0) | ||||||
|       summaly: |       summaly: | ||||||
|         specifier: github:misskey-dev/summaly |         specifier: github:misskey-dev/summaly | ||||||
|         version: github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7 |         version: github.com/misskey-dev/summaly/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc | ||||||
|       vite-plugin-turbosnap: |       vite-plugin-turbosnap: | ||||||
|         specifier: 1.0.2 |         specifier: 1.0.2 | ||||||
|         version: 1.0.2 |         version: 1.0.2 | ||||||
|  | @ -5345,7 +5345,7 @@ packages: | ||||||
|     hasBin: true |     hasBin: true | ||||||
|     requiresBuild: true |     requiresBuild: true | ||||||
|     dependencies: |     dependencies: | ||||||
|       detect-libc: 2.0.2 |       detect-libc: 2.0.1 | ||||||
|       https-proxy-agent: 5.0.1 |       https-proxy-agent: 5.0.1 | ||||||
|       make-dir: 3.1.0 |       make-dir: 3.1.0 | ||||||
|       node-fetch: 2.6.11 |       node-fetch: 2.6.11 | ||||||
|  | @ -11496,6 +11496,13 @@ packages: | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|  |   /detect-libc@2.0.1: | ||||||
|  |     resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} | ||||||
|  |     engines: {node: '>=8'} | ||||||
|  |     requiresBuild: true | ||||||
|  |     dev: false | ||||||
|  |     optional: true | ||||||
|  | 
 | ||||||
|   /detect-libc@2.0.2: |   /detect-libc@2.0.2: | ||||||
|     resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} |     resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|  | @ -22122,8 +22129,8 @@ packages: | ||||||
|       react-dom: 18.2.0(react@18.2.0) |       react-dom: 18.2.0(react@18.2.0) | ||||||
|     dev: true |     dev: true | ||||||
| 
 | 
 | ||||||
|   github.com/misskey-dev/summaly/d2d8db49943ccb201c1b1b283e9d0a630519fac7: |   github.com/misskey-dev/summaly/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc: | ||||||
|     resolution: {tarball: https://codeload.github.com/misskey-dev/summaly/tar.gz/d2d8db49943ccb201c1b1b283e9d0a630519fac7} |     resolution: {tarball: https://codeload.github.com/misskey-dev/summaly/tar.gz/089a0ad8e8c780e5c088b1c528aa95c5827cbdcc} | ||||||
|     name: summaly |     name: summaly | ||||||
|     version: 4.0.2 |     version: 4.0.2 | ||||||
|     dependencies: |     dependencies: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue