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