2023-06-10 04:45:11 +00:00
|
|
|
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
2022-09-17 18:27:08 +00:00
|
|
|
import { DI } from '@/di-symbols.js';
|
2023-02-15 04:06:06 +00:00
|
|
|
import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js';
|
2022-09-20 20:33:11 +00:00
|
|
|
import type { Config } from '@/config.js';
|
2023-04-04 06:56:47 +00:00
|
|
|
import { MemoryKVCache } from '@/misc/cache.js';
|
2022-09-17 18:27:08 +00:00
|
|
|
import type { UserPublickey } from '@/models/entities/UserPublickey.js';
|
2023-04-04 08:32:09 +00:00
|
|
|
import { CacheService } from '@/core/CacheService.js';
|
2022-09-17 18:27:08 +00:00
|
|
|
import type { Note } from '@/models/entities/Note.js';
|
2022-12-04 06:03:09 +00:00
|
|
|
import { bindThis } from '@/decorators.js';
|
enhance: account migration (#10592)
* copy block and mute then create follow and unfollow jobs
* copy block and mute and update lists when detecting an account has moved
* no need to care promise orders
* refactor updating actor and target
* automatically accept if a locked account had accepted an old account
* fix exception format
* prevent the old account from calling some endpoints
* do not unfollow when moving
* adjust following and follower counts
* check movedToUri when receiving a follow request
* skip if no need to adjust
* Revert "disable account migration"
This reverts commit 2321214c98591bcfe1385c1ab5bf0ff7b471ae1d.
* fix translation specifier
* fix checking alsoKnownAs and uri
* fix updating account
* fix refollowing locked account
* decrease followersCount if followed by the old account
* adjust following and followers counts when unfollowing
* fix copying mutings
* prohibit moved account from moving again
* fix move service
* allow app creation after moving
* fix lint
* remove unnecessary field
* fix cache update
* add e2e test
* add e2e test of accepting the new account automatically
* force follow if any error happens
* remove unnecessary joins
* use Array.map instead of for const of
* ユーザーリストの移行は追加のみを行う
* nanka iroiro
* fix misskey-js?
* :v:
* 移行を行ったアカウントからのフォローリクエストの自動許可を調整
* newUriを外に出す
* newUriを外に出す2
* clean up
* fix newUri
* prevent moving if the destination account has already moved
* set alsoKnownAs via /i/update
* fix database initialization
* add return type
* prohibit updating alsoKnownAs after moving
* skip to add to alsoKnownAs if toUrl is known
* skip adding to the list if it already has
* use Acct.parse instead
* rename error code
* :art:
* 制限を5から10に緩和
* movedTo(Uri), alsoKnownAsはユーザーidを返すように
* test api res
* fix
* 元アカウントはミュートし続ける
* :art:
* unfollow
* fix
* getUserUriをUserEntityServiceに
* ?
* job!
* :art:
* instance => server
* accountMovedShort, forbiddenBecauseYouAreMigrated
* accountMovedShort
* fix test
* import, pin禁止
* 実績を凍結する
* clean up
* :v:
* change message
* ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに
* Revert "ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに"
This reverts commit 3bd7be35d8aa455cb01ae58f8172a71a50485db1.
* validateAlsoKnownAs
* 移行後2時間以内はインポート可能なファイルサイズを拡大
* clean up
* どうせactorをupdatePersonで更新するならupdatePersonしか移行処理を発行しないことにする
* handle error?
* リモートからの移行処理の条件を是正
* log, port
* fix
* fix
* enhance(dev): non-production環境でhttpサーバー間でもユーザー、ノートの連合が可能なように
* refactor (use checkHttps)
* MISSKEY_WEBFINGER_USE_HTTP
* Environment Variable readme
* NEVER USE IN PRODUCTION
* fix punyHost
* fix indent
* fix
* experimental
---------
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-04-29 15:09:29 +00:00
|
|
|
import { LocalUser, RemoteUser } from '@/models/entities/User.js';
|
2022-09-17 18:27:08 +00:00
|
|
|
import { getApId } from './type.js';
|
|
|
|
import { ApPersonService } from './models/ApPersonService.js';
|
|
|
|
import type { IObject } from './type.js';
|
|
|
|
|
|
|
|
export type UriParseResult = {
|
|
|
|
/** wether the URI was generated by us */
|
|
|
|
local: true;
|
|
|
|
/** id in DB */
|
|
|
|
id: string;
|
|
|
|
/** hint of type, e.g. "notes", "users" */
|
|
|
|
type: string;
|
|
|
|
/** any remaining text after type and id, not including the slash after id. undefined if empty */
|
|
|
|
rest?: string;
|
|
|
|
} | {
|
|
|
|
/** wether the URI was generated by us */
|
|
|
|
local: false;
|
|
|
|
/** uri in DB */
|
|
|
|
uri: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
@Injectable()
|
2023-06-10 04:45:11 +00:00
|
|
|
export class ApDbResolverService implements OnApplicationShutdown {
|
2023-04-04 06:56:47 +00:00
|
|
|
private publicKeyCache: MemoryKVCache<UserPublickey | null>;
|
|
|
|
private publicKeyByUserIdCache: MemoryKVCache<UserPublickey | null>;
|
2022-09-17 18:27:08 +00:00
|
|
|
|
|
|
|
constructor(
|
|
|
|
@Inject(DI.config)
|
|
|
|
private config: Config,
|
|
|
|
|
|
|
|
@Inject(DI.usersRepository)
|
|
|
|
private usersRepository: UsersRepository,
|
|
|
|
|
|
|
|
@Inject(DI.notesRepository)
|
|
|
|
private notesRepository: NotesRepository,
|
|
|
|
|
|
|
|
@Inject(DI.userPublickeysRepository)
|
|
|
|
private userPublickeysRepository: UserPublickeysRepository,
|
|
|
|
|
2023-04-04 08:32:09 +00:00
|
|
|
private cacheService: CacheService,
|
2022-09-17 18:27:08 +00:00
|
|
|
private apPersonService: ApPersonService,
|
|
|
|
) {
|
2023-04-04 06:56:47 +00:00
|
|
|
this.publicKeyCache = new MemoryKVCache<UserPublickey | null>(Infinity);
|
|
|
|
this.publicKeyByUserIdCache = new MemoryKVCache<UserPublickey | null>(Infinity);
|
2022-09-17 18:27:08 +00:00
|
|
|
}
|
|
|
|
|
2022-12-04 06:03:09 +00:00
|
|
|
@bindThis
|
2022-09-17 18:27:08 +00:00
|
|
|
public parseUri(value: string | IObject): UriParseResult {
|
2023-07-05 23:47:47 +00:00
|
|
|
const separator = '/';
|
|
|
|
|
|
|
|
const uri = new URL(getApId(value));
|
|
|
|
if (uri.origin !== this.config.url) return { local: false, uri: uri.href };
|
|
|
|
|
|
|
|
const [, type, id, ...rest] = uri.pathname.split(separator);
|
|
|
|
return {
|
|
|
|
local: true,
|
|
|
|
type,
|
|
|
|
id,
|
|
|
|
rest: rest.length === 0 ? undefined : rest.join(separator),
|
|
|
|
};
|
2022-09-17 18:27:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* AP Note => Misskey Note in DB
|
|
|
|
*/
|
2022-12-04 06:03:09 +00:00
|
|
|
@bindThis
|
2022-09-17 18:27:08 +00:00
|
|
|
public async getNoteFromApId(value: string | IObject): Promise<Note | null> {
|
|
|
|
const parsed = this.parseUri(value);
|
|
|
|
|
|
|
|
if (parsed.local) {
|
|
|
|
if (parsed.type !== 'notes') return null;
|
|
|
|
|
|
|
|
return await this.notesRepository.findOneBy({
|
|
|
|
id: parsed.id,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return await this.notesRepository.findOneBy({
|
|
|
|
uri: parsed.uri,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* AP Person => Misskey User in DB
|
|
|
|
*/
|
2022-12-04 06:03:09 +00:00
|
|
|
@bindThis
|
enhance: account migration (#10592)
* copy block and mute then create follow and unfollow jobs
* copy block and mute and update lists when detecting an account has moved
* no need to care promise orders
* refactor updating actor and target
* automatically accept if a locked account had accepted an old account
* fix exception format
* prevent the old account from calling some endpoints
* do not unfollow when moving
* adjust following and follower counts
* check movedToUri when receiving a follow request
* skip if no need to adjust
* Revert "disable account migration"
This reverts commit 2321214c98591bcfe1385c1ab5bf0ff7b471ae1d.
* fix translation specifier
* fix checking alsoKnownAs and uri
* fix updating account
* fix refollowing locked account
* decrease followersCount if followed by the old account
* adjust following and followers counts when unfollowing
* fix copying mutings
* prohibit moved account from moving again
* fix move service
* allow app creation after moving
* fix lint
* remove unnecessary field
* fix cache update
* add e2e test
* add e2e test of accepting the new account automatically
* force follow if any error happens
* remove unnecessary joins
* use Array.map instead of for const of
* ユーザーリストの移行は追加のみを行う
* nanka iroiro
* fix misskey-js?
* :v:
* 移行を行ったアカウントからのフォローリクエストの自動許可を調整
* newUriを外に出す
* newUriを外に出す2
* clean up
* fix newUri
* prevent moving if the destination account has already moved
* set alsoKnownAs via /i/update
* fix database initialization
* add return type
* prohibit updating alsoKnownAs after moving
* skip to add to alsoKnownAs if toUrl is known
* skip adding to the list if it already has
* use Acct.parse instead
* rename error code
* :art:
* 制限を5から10に緩和
* movedTo(Uri), alsoKnownAsはユーザーidを返すように
* test api res
* fix
* 元アカウントはミュートし続ける
* :art:
* unfollow
* fix
* getUserUriをUserEntityServiceに
* ?
* job!
* :art:
* instance => server
* accountMovedShort, forbiddenBecauseYouAreMigrated
* accountMovedShort
* fix test
* import, pin禁止
* 実績を凍結する
* clean up
* :v:
* change message
* ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに
* Revert "ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに"
This reverts commit 3bd7be35d8aa455cb01ae58f8172a71a50485db1.
* validateAlsoKnownAs
* 移行後2時間以内はインポート可能なファイルサイズを拡大
* clean up
* どうせactorをupdatePersonで更新するならupdatePersonしか移行処理を発行しないことにする
* handle error?
* リモートからの移行処理の条件を是正
* log, port
* fix
* fix
* enhance(dev): non-production環境でhttpサーバー間でもユーザー、ノートの連合が可能なように
* refactor (use checkHttps)
* MISSKEY_WEBFINGER_USE_HTTP
* Environment Variable readme
* NEVER USE IN PRODUCTION
* fix punyHost
* fix indent
* fix
* experimental
---------
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-04-29 15:09:29 +00:00
|
|
|
public async getUserFromApId(value: string | IObject): Promise<LocalUser | RemoteUser | null> {
|
2022-09-17 18:27:08 +00:00
|
|
|
const parsed = this.parseUri(value);
|
|
|
|
|
|
|
|
if (parsed.local) {
|
|
|
|
if (parsed.type !== 'users') return null;
|
|
|
|
|
2023-04-04 08:32:09 +00:00
|
|
|
return await this.cacheService.userByIdCache.fetchMaybe(parsed.id, () => this.usersRepository.findOneBy({
|
2022-09-17 18:27:08 +00:00
|
|
|
id: parsed.id,
|
enhance: account migration (#10592)
* copy block and mute then create follow and unfollow jobs
* copy block and mute and update lists when detecting an account has moved
* no need to care promise orders
* refactor updating actor and target
* automatically accept if a locked account had accepted an old account
* fix exception format
* prevent the old account from calling some endpoints
* do not unfollow when moving
* adjust following and follower counts
* check movedToUri when receiving a follow request
* skip if no need to adjust
* Revert "disable account migration"
This reverts commit 2321214c98591bcfe1385c1ab5bf0ff7b471ae1d.
* fix translation specifier
* fix checking alsoKnownAs and uri
* fix updating account
* fix refollowing locked account
* decrease followersCount if followed by the old account
* adjust following and followers counts when unfollowing
* fix copying mutings
* prohibit moved account from moving again
* fix move service
* allow app creation after moving
* fix lint
* remove unnecessary field
* fix cache update
* add e2e test
* add e2e test of accepting the new account automatically
* force follow if any error happens
* remove unnecessary joins
* use Array.map instead of for const of
* ユーザーリストの移行は追加のみを行う
* nanka iroiro
* fix misskey-js?
* :v:
* 移行を行ったアカウントからのフォローリクエストの自動許可を調整
* newUriを外に出す
* newUriを外に出す2
* clean up
* fix newUri
* prevent moving if the destination account has already moved
* set alsoKnownAs via /i/update
* fix database initialization
* add return type
* prohibit updating alsoKnownAs after moving
* skip to add to alsoKnownAs if toUrl is known
* skip adding to the list if it already has
* use Acct.parse instead
* rename error code
* :art:
* 制限を5から10に緩和
* movedTo(Uri), alsoKnownAsはユーザーidを返すように
* test api res
* fix
* 元アカウントはミュートし続ける
* :art:
* unfollow
* fix
* getUserUriをUserEntityServiceに
* ?
* job!
* :art:
* instance => server
* accountMovedShort, forbiddenBecauseYouAreMigrated
* accountMovedShort
* fix test
* import, pin禁止
* 実績を凍結する
* clean up
* :v:
* change message
* ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに
* Revert "ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに"
This reverts commit 3bd7be35d8aa455cb01ae58f8172a71a50485db1.
* validateAlsoKnownAs
* 移行後2時間以内はインポート可能なファイルサイズを拡大
* clean up
* どうせactorをupdatePersonで更新するならupdatePersonしか移行処理を発行しないことにする
* handle error?
* リモートからの移行処理の条件を是正
* log, port
* fix
* fix
* enhance(dev): non-production環境でhttpサーバー間でもユーザー、ノートの連合が可能なように
* refactor (use checkHttps)
* MISSKEY_WEBFINGER_USE_HTTP
* Environment Variable readme
* NEVER USE IN PRODUCTION
* fix punyHost
* fix indent
* fix
* experimental
---------
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-04-29 15:09:29 +00:00
|
|
|
}).then(x => x ?? undefined)) as LocalUser | undefined ?? null;
|
2022-09-17 18:27:08 +00:00
|
|
|
} else {
|
2023-04-04 08:32:09 +00:00
|
|
|
return await this.cacheService.uriPersonCache.fetch(parsed.uri, () => this.usersRepository.findOneBy({
|
2022-09-17 18:27:08 +00:00
|
|
|
uri: parsed.uri,
|
enhance: account migration (#10592)
* copy block and mute then create follow and unfollow jobs
* copy block and mute and update lists when detecting an account has moved
* no need to care promise orders
* refactor updating actor and target
* automatically accept if a locked account had accepted an old account
* fix exception format
* prevent the old account from calling some endpoints
* do not unfollow when moving
* adjust following and follower counts
* check movedToUri when receiving a follow request
* skip if no need to adjust
* Revert "disable account migration"
This reverts commit 2321214c98591bcfe1385c1ab5bf0ff7b471ae1d.
* fix translation specifier
* fix checking alsoKnownAs and uri
* fix updating account
* fix refollowing locked account
* decrease followersCount if followed by the old account
* adjust following and followers counts when unfollowing
* fix copying mutings
* prohibit moved account from moving again
* fix move service
* allow app creation after moving
* fix lint
* remove unnecessary field
* fix cache update
* add e2e test
* add e2e test of accepting the new account automatically
* force follow if any error happens
* remove unnecessary joins
* use Array.map instead of for const of
* ユーザーリストの移行は追加のみを行う
* nanka iroiro
* fix misskey-js?
* :v:
* 移行を行ったアカウントからのフォローリクエストの自動許可を調整
* newUriを外に出す
* newUriを外に出す2
* clean up
* fix newUri
* prevent moving if the destination account has already moved
* set alsoKnownAs via /i/update
* fix database initialization
* add return type
* prohibit updating alsoKnownAs after moving
* skip to add to alsoKnownAs if toUrl is known
* skip adding to the list if it already has
* use Acct.parse instead
* rename error code
* :art:
* 制限を5から10に緩和
* movedTo(Uri), alsoKnownAsはユーザーidを返すように
* test api res
* fix
* 元アカウントはミュートし続ける
* :art:
* unfollow
* fix
* getUserUriをUserEntityServiceに
* ?
* job!
* :art:
* instance => server
* accountMovedShort, forbiddenBecauseYouAreMigrated
* accountMovedShort
* fix test
* import, pin禁止
* 実績を凍結する
* clean up
* :v:
* change message
* ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに
* Revert "ブロック, フォロー, ミュート, リストのインポートファイルの制限を32MiBに"
This reverts commit 3bd7be35d8aa455cb01ae58f8172a71a50485db1.
* validateAlsoKnownAs
* 移行後2時間以内はインポート可能なファイルサイズを拡大
* clean up
* どうせactorをupdatePersonで更新するならupdatePersonしか移行処理を発行しないことにする
* handle error?
* リモートからの移行処理の条件を是正
* log, port
* fix
* fix
* enhance(dev): non-production環境でhttpサーバー間でもユーザー、ノートの連合が可能なように
* refactor (use checkHttps)
* MISSKEY_WEBFINGER_USE_HTTP
* Environment Variable readme
* NEVER USE IN PRODUCTION
* fix punyHost
* fix indent
* fix
* experimental
---------
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-04-29 15:09:29 +00:00
|
|
|
})) as RemoteUser | null;
|
2022-09-17 18:27:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* AP KeyId => Misskey User and Key
|
|
|
|
*/
|
2022-12-04 06:03:09 +00:00
|
|
|
@bindThis
|
2022-09-17 18:27:08 +00:00
|
|
|
public async getAuthUserFromKeyId(keyId: string): Promise<{
|
2023-02-13 06:50:22 +00:00
|
|
|
user: RemoteUser;
|
2022-09-17 18:27:08 +00:00
|
|
|
key: UserPublickey;
|
|
|
|
} | null> {
|
2022-09-18 18:11:50 +00:00
|
|
|
const key = await this.publicKeyCache.fetch(keyId, async () => {
|
2022-09-17 18:27:08 +00:00
|
|
|
const key = await this.userPublickeysRepository.findOneBy({
|
|
|
|
keyId,
|
|
|
|
});
|
2023-07-07 22:08:16 +00:00
|
|
|
|
2022-09-17 18:27:08 +00:00
|
|
|
if (key == null) return null;
|
|
|
|
|
|
|
|
return key;
|
|
|
|
}, key => key != null);
|
|
|
|
|
|
|
|
if (key == null) return null;
|
|
|
|
|
|
|
|
return {
|
2023-04-04 08:32:09 +00:00
|
|
|
user: await this.cacheService.findUserById(key.userId) as RemoteUser,
|
2022-09-17 18:27:08 +00:00
|
|
|
key,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* AP Actor id => Misskey User and Key
|
|
|
|
*/
|
2022-12-04 06:03:09 +00:00
|
|
|
@bindThis
|
2022-09-17 18:27:08 +00:00
|
|
|
public async getAuthUserFromApId(uri: string): Promise<{
|
2023-02-13 06:50:22 +00:00
|
|
|
user: RemoteUser;
|
2022-09-17 18:27:08 +00:00
|
|
|
key: UserPublickey | null;
|
|
|
|
} | null> {
|
2023-02-13 06:50:22 +00:00
|
|
|
const user = await this.apPersonService.resolvePerson(uri) as RemoteUser;
|
2022-09-17 18:27:08 +00:00
|
|
|
|
|
|
|
if (user == null) return null;
|
|
|
|
|
2023-07-07 22:08:16 +00:00
|
|
|
const key = await this.publicKeyByUserIdCache.fetch(user.id, () => this.userPublickeysRepository.findOneBy({ userId: user.id }), v => v != null);
|
2022-09-17 18:27:08 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
user,
|
|
|
|
key,
|
|
|
|
};
|
|
|
|
}
|
2023-06-10 04:45:11 +00:00
|
|
|
|
|
|
|
@bindThis
|
|
|
|
public dispose(): void {
|
|
|
|
this.publicKeyCache.dispose();
|
|
|
|
this.publicKeyByUserIdCache.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
@bindThis
|
|
|
|
public onApplicationShutdown(signal?: string | undefined): void {
|
|
|
|
this.dispose();
|
|
|
|
}
|
2022-09-17 18:27:08 +00:00
|
|
|
}
|