unify note create/edit logic to fix various logic bugs and validation gaps

This commit is contained in:
Hazelnoot 2025-09-18 14:16:58 -04:00
parent 24bc1c653d
commit edb74066da
5 changed files with 93 additions and 144 deletions

View file

@ -303,31 +303,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (renote == null) {
throw new ApiError(meta.errors.noSuchRenoteTarget);
} else if (isRenote(renote) && !isQuote(renote)) {
throw new ApiError(meta.errors.cannotReRenote);
} else if (!(await this.noteVisibilityService.checkNoteVisibilityAsync(renote, me)).accessible) {
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
}
// Check blocking
if (renote.userId !== me.id) {
const blockExist = await this.blockingsRepository.exists({
where: {
blockerId: renote.userId,
blockeeId: me.id,
},
});
if (blockExist) {
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
}
if (renote.visibility === 'followers' && renote.userId !== me.id) {
// 他人のfollowers noteはreject
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
} else if (renote.visibility === 'specified') {
// specified / direct noteはreject
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
}
if (renote.channelId && renote.channelId !== ps.channelId) {
@ -351,26 +326,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (reply == null) {
throw new ApiError(meta.errors.noSuchReplyTarget);
} else if (isRenote(reply) && !isQuote(reply)) {
throw new ApiError(meta.errors.cannotReplyToPureRenote);
} else if (!(await this.noteVisibilityService.checkNoteVisibilityAsync(reply, me)).accessible) {
throw new ApiError(meta.errors.cannotReplyToInvisibleNote);
} else if (reply.visibility === 'specified' && ps.visibility !== 'specified') {
throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility);
}
// Check blocking
if (reply.userId !== me.id) {
const blockExist = await this.blockingsRepository.exists({
where: {
blockerId: reply.userId,
blockeeId: me.id,
},
});
if (blockExist) {
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
}
}
if (ps.poll) {
@ -430,6 +388,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.quoteDisabledForUser);
} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
throw new ApiError(meta.errors.cannotReRenote);
} else if (e.id === 'b6352a84-e5cd-4b05-a26c-63437a6b98ba') {
throw new ApiError(meta.errors.youHaveBeenBlocked);
} else if (e.id === 'be9529e9-fe72-4de0-ae43-0b363c4938af') {
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
} else if (e.id === '3ac74a84-8fd5-4bb0-870f-01804f82ce15') {
throw new ApiError(meta.errors.cannotReplyToPureRenote);
} else if (e.id === 'b98980fa-3780-406c-a935-b6d0eeee10d1') {
throw new ApiError(meta.errors.cannotReplyToInvisibleNote);
}
}
throw e;

View file

@ -347,11 +347,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
}
let renote: MiNote | null = null;
if (ps.renoteId === ps.editId) {
throw new ApiError(meta.errors.cannotQuoteCurrentPost);
}
if (ps.renoteId != null) {
// Fetch renote to note
renote = await this.notesRepository.findOneBy({ id: ps.renoteId });
@ -360,27 +355,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.noSuchRenoteTarget);
}
// Check blocking
if (renote.userId !== me.id) {
const blockExist = await this.blockingsRepository.exists({
where: {
blockerId: renote.userId,
blockeeId: me.id,
},
});
if (blockExist) {
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
}
if (renote.visibility === 'followers' && renote.userId !== me.id) {
// 他人のfollowers noteはreject
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
} else if (renote.visibility === 'specified') {
// specified / direct noteはreject
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
}
if (renote.channelId && renote.channelId !== ps.channelId) {
// チャンネルのノートに対しリノート要求がきたとき、チャンネル外へのリノート可否をチェック
// リートのユースケースのうち、チャンネル内→チャンネル外は少数だと考えられるため、JOINはせず必要な時に都度取得する
@ -402,26 +376,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (reply == null) {
throw new ApiError(meta.errors.noSuchReplyTarget);
} else if (isRenote(reply) && !isQuote(reply)) {
throw new ApiError(meta.errors.cannotReplyToPureRenote);
} else if (!(await this.noteVisibilityService.checkNoteVisibilityAsync(reply, me)).accessible) {
throw new ApiError(meta.errors.cannotReplyToInvisibleNote);
} else if (reply.visibility === 'specified' && ps.visibility !== 'specified') {
throw new ApiError(meta.errors.cannotReplyToSpecifiedVisibilityNoteWithExtendedVisibility);
}
// Check blocking
if (reply.userId !== me.id) {
const blockExist = await this.blockingsRepository.exists({
where: {
blockerId: reply.userId,
blockeeId: me.id,
},
});
if (blockExist) {
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
}
}
if (ps.poll) {
@ -477,10 +434,20 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
throw new ApiError(meta.errors.containsTooManyMentions);
} else if (e.id === '1c0ea108-d1e3-4e8e-aa3f-4d2487626153') {
throw new ApiError(meta.errors.quoteDisabledForUser);
} else if (e.id === '33510210-8452-094c-6227-4a6c05d99f02') {
throw new ApiError(meta.errors.cannotQuoteCurrentPost);
} else if (e.id === 'ea93b7c2-3d6c-4e10-946b-00d50b1a75cb') {
throw new ApiError(meta.errors.cannotQuoteaQuoteOfCurrentPost);
} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
throw new ApiError(meta.errors.cannotReRenote);
} else if (e.id === 'b6352a84-e5cd-4b05-a26c-63437a6b98ba') {
throw new ApiError(meta.errors.youHaveBeenBlocked);
} else if (e.id === 'be9529e9-fe72-4de0-ae43-0b363c4938af') {
throw new ApiError(meta.errors.cannotRenoteDueToVisibility);
} else if (e.id === '3ac74a84-8fd5-4bb0-870f-01804f82ce15') {
throw new ApiError(meta.errors.cannotReplyToPureRenote);
} else if (e.id === 'b98980fa-3780-406c-a935-b6d0eeee10d1') {
throw new ApiError(meta.errors.cannotReplyToInvisibleNote);
}
}
throw e;