Merge branch 'chore-api-R30906' into stream-types
This commit is contained in:
		
						commit
						e9b9afbd2a
					
				
							
								
								
									
										13
									
								
								CHANGELOG.md
								
								
								
								
							
							
						
						
									
										13
									
								
								CHANGELOG.md
								
								
								
								
							|  | @ -7,6 +7,19 @@ | |||
| 
 | ||||
| --> | ||||
| 
 | ||||
| ## 12.x.x (unreleased) | ||||
| 
 | ||||
| ### Improvements | ||||
| - リモートユーザーのDeleteアクティビティに対応 | ||||
| 
 | ||||
| ### Bugfixes | ||||
| 
 | ||||
| ## 12.90.1 (2021/09/05) | ||||
| 
 | ||||
| ### Bugfixes | ||||
| - Dockerfileを修正 | ||||
| - ノート翻訳時に公開範囲が考慮されていない問題を修正 | ||||
| 
 | ||||
| ## 12.90.0 (2021/09/04) | ||||
| 
 | ||||
| ### Improvements | ||||
|  |  | |||
|  | @ -1150,6 +1150,10 @@ _permissions: | |||
|   "write:user-groups": "ユーザーグループを操作する" | ||||
|   "read:channels": "チャンネルを見る" | ||||
|   "write:channels": "チャンネルを操作する" | ||||
|   "read:gallery": "ギャラリーを見る" | ||||
|   "write:gallery": "ギャラリーを操作する" | ||||
|   "read:gallery-likes": "ギャラリーのいいねを見る" | ||||
|   "write:gallery-likes": "ギャラリーのいいねを操作する" | ||||
| 
 | ||||
| _auth: | ||||
|   shareAccess: "「{name}」がアカウントにアクセスすることを許可しますか?" | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| { | ||||
| 	"name": "misskey", | ||||
| 	"author": "syuilo <syuilotan@yahoo.co.jp>", | ||||
| 	"version": "12.90.0", | ||||
| 	"version": "12.90.1", | ||||
| 	"codename": "indigo", | ||||
| 	"repository": { | ||||
| 		"type": "git", | ||||
|  |  | |||
|  | @ -32,3 +32,4 @@ export const kinds = [ | |||
| 	'read:gallery-likes', | ||||
| 	'write:gallery-likes', | ||||
| ]; | ||||
| // IF YOU ADD KINDS(PERMISSIONS), YOU MUST ADD TRANSLATIONS (under _permissions).
 | ||||
|  |  | |||
|  | @ -18,7 +18,57 @@ export class NoteRepository extends Repository<Note> { | |||
| 		return x.trim().length <= 100; | ||||
| 	} | ||||
| 
 | ||||
| 	public async isVisibleForMe(note: Note, meId: User['id'] | null): Promise<boolean> { | ||||
| 		// visibility が specified かつ自分が指定されていなかったら非表示
 | ||||
| 		if (note.visibility === 'specified') { | ||||
| 			if (meId == null) { | ||||
| 				return false; | ||||
| 			} else if (meId === note.userId) { | ||||
| 				return true; | ||||
| 			} else { | ||||
| 				// 指定されているかどうか
 | ||||
| 				const specified = note.visibleUserIds.some((id: any) => meId === id); | ||||
| 
 | ||||
| 				if (specified) { | ||||
| 					return true; | ||||
| 				} else { | ||||
| 					return false; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示
 | ||||
| 		if (note.visibility === 'followers') { | ||||
| 			if (meId == null) { | ||||
| 				return false; | ||||
| 			} else if (meId === note.userId) { | ||||
| 				return true; | ||||
| 			} else if (note.reply && (meId === note.reply.userId)) { | ||||
| 				// 自分の投稿に対するリプライ
 | ||||
| 				return true; | ||||
| 			} else if (note.mentions && note.mentions.some(id => meId === id)) { | ||||
| 				// 自分へのメンション
 | ||||
| 				return true; | ||||
| 			} else { | ||||
| 				// フォロワーかどうか
 | ||||
| 				const following = await Followings.findOne({ | ||||
| 					followeeId: note.userId, | ||||
| 					followerId: meId | ||||
| 				}); | ||||
| 
 | ||||
| 				if (following == null) { | ||||
| 					return false; | ||||
| 				} else { | ||||
| 					return true; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	private async hideNote(packedNote: PackedNote, meId: User['id'] | null) { | ||||
| 		// TODO: isVisibleForMe を使うようにしても良さそう(型違うけど)
 | ||||
| 		let hide = false; | ||||
| 
 | ||||
| 		// visibility が specified かつ自分が指定されていなかったら非表示
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import { Note } from '@/models/entities/note'; | |||
| import { NoteReaction } from '@/models/entities/note-reaction'; | ||||
| import { User } from '@/models/entities/user'; | ||||
| import { aggregateNoteEmojis, prefetchEmojis } from '@/misc/populate-emojis'; | ||||
| import { notificationTypes } from '@/types'; | ||||
| 
 | ||||
| export type PackedNotification = SchemaType<typeof packedNotificationSchema>; | ||||
| 
 | ||||
|  | @ -124,20 +125,41 @@ export const packedNotificationSchema = { | |||
| 			optional: false as const, nullable: false as const, | ||||
| 			format: 'date-time', | ||||
| 		}, | ||||
| 		isRead: { | ||||
| 			type: 'boolean' as const, | ||||
| 			optional: false as const, nullable: false as const, | ||||
| 		}, | ||||
| 		type: { | ||||
| 			type: 'string' as const, | ||||
| 			optional: false as const, nullable: false as const, | ||||
| 			enum: ['follow', 'followRequestAccepted', 'receiveFollowRequest', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote'], | ||||
| 		}, | ||||
| 		userId: { | ||||
| 			type: 'string' as const, | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 			format: 'id', | ||||
| 			enum: [...notificationTypes], | ||||
| 		}, | ||||
| 		user: { | ||||
| 			type: 'object' as const, | ||||
| 			ref: 'User', | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 		}, | ||||
| 		userId: { | ||||
| 			type: 'string' as const, | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 			format: 'id', | ||||
| 		}, | ||||
| 		note: { | ||||
| 			type: 'object' as const, | ||||
| 			ref: 'Note', | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 		}, | ||||
| 		reaction: { | ||||
| 			type: 'string' as const, | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 		}, | ||||
| 		body: { | ||||
| 			type: 'string' as const, | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 		}, | ||||
| 		icon: { | ||||
| 			type: 'string' as const, | ||||
| 			optional: true as const, nullable: true as const, | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
|  |  | |||
|  | @ -0,0 +1,26 @@ | |||
| import { apLogger } from '../../logger'; | ||||
| import { createDeleteAccountJob } from '@/queue'; | ||||
| import { IRemoteUser } from '@/models/entities/user'; | ||||
| import { Users } from '@/models/index'; | ||||
| 
 | ||||
| const logger = apLogger; | ||||
| 
 | ||||
| export async function deleteActor(actor: IRemoteUser, uri: string): Promise<string> { | ||||
| 	logger.info(`Deleting the Actor: ${uri}`); | ||||
| 
 | ||||
| 	if (actor.uri !== uri) { | ||||
| 		return `skip: delete actor ${actor.uri} !== ${uri}`; | ||||
| 	} | ||||
| 
 | ||||
| 	if (actor.isDeleted) { | ||||
| 		logger.info(`skip: already deleted`); | ||||
| 	} | ||||
| 
 | ||||
| 	const job = await createDeleteAccountJob(actor); | ||||
| 
 | ||||
| 	await Users.update(actor.id, { | ||||
| 		isDeleted: true, | ||||
| 	}); | ||||
| 
 | ||||
| 	return `ok: queued ${job.name} ${job.id}`; | ||||
| } | ||||
|  | @ -2,6 +2,7 @@ import deleteNote from './note'; | |||
| import { IRemoteUser } from '@/models/entities/user'; | ||||
| import { IDelete, getApId, isTombstone, IObject, validPost, validActor } from '../../type'; | ||||
| import { toSingle } from '@/prelude/array'; | ||||
| import { deleteActor } from './actor'; | ||||
| 
 | ||||
| /** | ||||
|  * 削除アクティビティを捌きます | ||||
|  | @ -41,7 +42,7 @@ export default async (actor: IRemoteUser, activity: IDelete): Promise<string> => | |||
| 	if (validPost.includes(formarType)) { | ||||
| 		return await deleteNote(actor, uri); | ||||
| 	} else if (validActor.includes(formarType)) { | ||||
| 		return `Delete Actor is not implanted`; | ||||
| 		return await deleteActor(actor, uri); | ||||
| 	} else { | ||||
| 		return `Unknown type ${formarType}`; | ||||
| 	} | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ import config from '@/config/index'; | |||
| import { getAgentByUrl } from '@/misc/fetch'; | ||||
| import { URLSearchParams } from 'url'; | ||||
| import { fetchMeta } from '@/misc/fetch-meta'; | ||||
| import { Notes } from '@/models'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	tags: ['notes'], | ||||
|  | @ -43,6 +44,10 @@ export default define(meta, async (ps, user) => { | |||
| 		throw e; | ||||
| 	}); | ||||
| 
 | ||||
| 	if (!(await Notes.isVisibleForMe(note, user ? user.id : null))) { | ||||
| 		return 204; // TODO: 良い感じのエラー返す
 | ||||
| 	} | ||||
| 
 | ||||
| 	if (note.text == null) { | ||||
| 		return 204; | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue