Compare commits
18 Commits
13.0.0-rc.
...
12.119.2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a5a74f4434 | ||
![]() |
993110d114 | ||
![]() |
fccd9c32e8 | ||
![]() |
58a3a0b7d4 | ||
![]() |
a2a1636c10 | ||
![]() |
46ec0303b7 | ||
![]() |
3b1669fb6b | ||
![]() |
09591fa4ae | ||
![]() |
85ce00adc0 | ||
![]() |
f25518af91 | ||
![]() |
b796aacf7f | ||
![]() |
ff24811676 | ||
![]() |
4c8a1867f0 | ||
![]() |
bce48dfee9 | ||
![]() |
c20311b8a7 | ||
![]() |
fb14ac50b8 | ||
![]() |
84d984bd31 | ||
![]() |
1bc856c451 |
@@ -9,6 +9,14 @@
|
||||
You should also include the user name that made the change.
|
||||
-->
|
||||
|
||||
## 12.119.2 (2022/12/04)
|
||||
### Bugfixes
|
||||
- Server: Backported versions mitigate isn't working @mei23
|
||||
|
||||
## 12.119.1 (2022/12/03)
|
||||
### Bugfixes
|
||||
- Server: Mitigate AP reference chain DoS vector @skehmatics
|
||||
|
||||
## 12.119.0 (2022/09/10)
|
||||
|
||||
### Improvements
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"version": "12.119.0",
|
||||
"version": "12.119.2",
|
||||
"codename": "indigo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -10,7 +10,7 @@ import { updatePerson } from '../../models/person.js';
|
||||
*/
|
||||
export default async (actor: CacheableRemoteUser, activity: IUpdate): Promise<string> => {
|
||||
if ('actor' in activity && actor.uri !== activity.actor) {
|
||||
return `skip: invalid actor`;
|
||||
return 'skip: invalid actor';
|
||||
}
|
||||
|
||||
apLogger.debug('Update');
|
||||
@@ -24,10 +24,10 @@ export default async (actor: CacheableRemoteUser, activity: IUpdate): Promise<st
|
||||
|
||||
if (isActor(object)) {
|
||||
await updatePerson(actor.uri!, resolver, object);
|
||||
return `ok: Person updated`;
|
||||
return 'ok: Person updated';
|
||||
} else if (getApType(object) === 'Question') {
|
||||
await updateQuestion(object).catch(e => console.log(e));
|
||||
return `ok: Question updated`;
|
||||
await updateQuestion(object, resolver).catch(e => console.log(e));
|
||||
return 'ok: Question updated';
|
||||
} else {
|
||||
return `skip: Unknown type: ${getApType(object)}`;
|
||||
}
|
||||
|
@@ -5,11 +5,9 @@ import { IObject, isMention, IApMention } from '../type.js';
|
||||
import Resolver from '../resolver.js';
|
||||
import { resolvePerson } from './person.js';
|
||||
|
||||
export async function extractApMentions(tags: IObject | IObject[] | null | undefined) {
|
||||
export async function extractApMentions(tags: IObject | IObject[] | null | undefined, resolver: Resolver) {
|
||||
const hrefs = unique(extractApMentionObjects(tags).map(x => x.href as string));
|
||||
|
||||
const resolver = new Resolver();
|
||||
|
||||
const limit = promiseLimit<CacheableUser | null>(2);
|
||||
const mentionedUsers = (await Promise.all(
|
||||
hrefs.map(x => limit(() => resolvePerson(x, resolver).catch(() => null))),
|
||||
|
@@ -97,7 +97,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s
|
||||
throw new Error('actor has been suspended');
|
||||
}
|
||||
|
||||
const noteAudience = await parseAudience(actor, note.to, note.cc);
|
||||
const noteAudience = await parseAudience(actor, note.to, note.cc, resolver);
|
||||
let visibility = noteAudience.visibility;
|
||||
const visibleUsers = noteAudience.visibleUsers;
|
||||
|
||||
@@ -111,7 +111,7 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s
|
||||
|
||||
let isTalk = note._misskey_talk && visibility === 'specified';
|
||||
|
||||
const apMentions = await extractApMentions(note.tag);
|
||||
const apMentions = await extractApMentions(note.tag, resolver);
|
||||
const apHashtags = await extractApHashtags(note.tag);
|
||||
|
||||
// 添付ファイル
|
||||
|
@@ -271,7 +271,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
|
||||
});
|
||||
//#endregion
|
||||
|
||||
await updateFeatured(user!.id).catch(err => logger.error(err));
|
||||
await updateFeatured(user!.id, resolver).catch(err => logger.error(err));
|
||||
|
||||
return user!;
|
||||
}
|
||||
@@ -384,7 +384,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
|
||||
followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined),
|
||||
});
|
||||
|
||||
await updateFeatured(exist.id).catch(err => logger.error(err));
|
||||
await updateFeatured(exist.id, resolver).catch(err => logger.error(err));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,14 +462,14 @@ export function analyzeAttachments(attachments: IObject | IObject[] | undefined)
|
||||
return { fields, services };
|
||||
}
|
||||
|
||||
export async function updateFeatured(userId: User['id']) {
|
||||
export async function updateFeatured(userId: User['id'], resolver?: Resolver) {
|
||||
const user = await Users.findOneByOrFail({ id: userId });
|
||||
if (!Users.isRemoteUser(user)) return;
|
||||
if (!user.featured) return;
|
||||
|
||||
logger.info(`Updating the featured: ${user.uri}`);
|
||||
|
||||
const resolver = new Resolver();
|
||||
if (resolver == null) resolver = new Resolver();
|
||||
|
||||
// Resolve to (Ordered)Collection Object
|
||||
const collection = await resolver.resolveCollection(user.featured);
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import config from '@/config/index.js';
|
||||
import { Notes, Polls } from '@/models/index.js';
|
||||
import { IPoll } from '@/models/entities/poll.js';
|
||||
import Resolver from '../resolver.js';
|
||||
import { IObject, IQuestion, isQuestion } from '../type.js';
|
||||
import { apLogger } from '../logger.js';
|
||||
import { Notes, Polls } from '@/models/index.js';
|
||||
import { IPoll } from '@/models/entities/poll.js';
|
||||
|
||||
export async function extractPollFromQuestion(source: string | IObject, resolver?: Resolver): Promise<IPoll> {
|
||||
if (resolver == null) resolver = new Resolver();
|
||||
@@ -40,7 +40,7 @@ export async function extractPollFromQuestion(source: string | IObject, resolver
|
||||
* @param uri URI of AP Question object
|
||||
* @returns true if updated
|
||||
*/
|
||||
export async function updateQuestion(value: any) {
|
||||
export async function updateQuestion(value: any, resolver?: Resolver) {
|
||||
const uri = typeof value === 'string' ? value : value.id;
|
||||
|
||||
// URIがこのサーバーを指しているならスキップ
|
||||
@@ -55,7 +55,7 @@ export async function updateQuestion(value: any) {
|
||||
//#endregion
|
||||
|
||||
// resolve new Question object
|
||||
const resolver = new Resolver();
|
||||
if (resolver == null) resolver = new Resolver();
|
||||
const question = await resolver.resolve(value) as IQuestion;
|
||||
apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`);
|
||||
|
||||
|
@@ -4,10 +4,7 @@ import { ILocalUser } from '@/models/entities/user.js';
|
||||
import { getInstanceActor } from '@/services/instance-actor.js';
|
||||
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||
import { extractDbHost, isSelfHost } from '@/misc/convert-host.js';
|
||||
import { signedGet } from './request.js';
|
||||
import { IObject, isCollectionOrOrderedCollection, ICollection, IOrderedCollection } from './type.js';
|
||||
import { FollowRequests, Notes, NoteReactions, Polls, Users } from '@/models/index.js';
|
||||
import { parseUri } from './db-resolver.js';
|
||||
import renderNote from '@/remote/activitypub/renderer/note.js';
|
||||
import { renderLike } from '@/remote/activitypub/renderer/like.js';
|
||||
import { renderPerson } from '@/remote/activitypub/renderer/person.js';
|
||||
@@ -15,13 +12,18 @@ import renderQuestion from '@/remote/activitypub/renderer/question.js';
|
||||
import renderCreate from '@/remote/activitypub/renderer/create.js';
|
||||
import { renderActivity } from '@/remote/activitypub/renderer/index.js';
|
||||
import renderFollow from '@/remote/activitypub/renderer/follow.js';
|
||||
import { parseUri } from './db-resolver.js';
|
||||
import { IObject, isCollectionOrOrderedCollection, ICollection, IOrderedCollection } from './type.js';
|
||||
import { signedGet } from './request.js';
|
||||
|
||||
export default class Resolver {
|
||||
private history: Set<string>;
|
||||
private user?: ILocalUser;
|
||||
private recursionLimit?: number;
|
||||
|
||||
constructor() {
|
||||
constructor(recursionLimit = 100) {
|
||||
this.history = new Set();
|
||||
this.recursionLimit = recursionLimit;
|
||||
}
|
||||
|
||||
public getHistory(): string[] {
|
||||
@@ -60,6 +62,10 @@ export default class Resolver {
|
||||
throw new Error('cannot resolve already resolved one');
|
||||
}
|
||||
|
||||
if (this.recursionLimit && this.history.size > this.recursionLimit) {
|
||||
throw new Error('hit recursion limit');
|
||||
}
|
||||
|
||||
this.history.add(value);
|
||||
|
||||
const host = extractDbHost(value);
|
||||
@@ -123,7 +129,7 @@ export default class Resolver {
|
||||
if (parsed.rest == null || !/^\w+$/.test(parsed.rest)) throw new Error('resolveLocal: invalid follow URI');
|
||||
|
||||
return Promise.all(
|
||||
[parsed.id, parsed.rest].map(id => Users.findOneByOrFail({ id }))
|
||||
[parsed.id, parsed.rest].map(id => Users.findOneByOrFail({ id })),
|
||||
)
|
||||
.then(([follower, followee]) => renderActivity(renderFollow(follower, followee, url)));
|
||||
default:
|
||||
|
Reference in New Issue
Block a user