getAuthUserFromApIdでupdatePersonの頻度を増やす

This commit is contained in:
tamaina 2024-03-01 18:29:30 +00:00
parent 9111b5c482
commit d86b8c8752
2 changed files with 48 additions and 41 deletions

View File

@ -116,6 +116,8 @@ export class ApDbResolverService implements OnApplicationShutdown {
/** /**
* AP Actor id => Misskey User and Key * AP Actor id => Misskey User and Key
* @param uri AP Actor id
* @param keyId Key id to find. If not specified, main key will be selected.
*/ */
@bindThis @bindThis
public async getAuthUserFromApId(uri: string, keyId?: string): Promise<{ public async getAuthUserFromApId(uri: string, keyId?: string): Promise<{
@ -125,50 +127,56 @@ export class ApDbResolverService implements OnApplicationShutdown {
const user = await this.apPersonService.resolvePerson(uri, undefined, true) as MiRemoteUser; const user = await this.apPersonService.resolvePerson(uri, undefined, true) as MiRemoteUser;
if (user.isDeleted) return null; if (user.isDeleted) return null;
const keys = await this.publicKeyByUserIdCache.fetch( const keys = await this.getPublicKeyByUserId(user.id);
user.id,
() => this.userPublickeysRepository.find({ where: { userId: user.id } }),
v => v != null,
);
if (keys == null || !Array.isArray(keys)) return null; if (keys == null || !Array.isArray(keys)) return { user, key: null };
if (keys.length === 0) { if (!keyId) {
return { // mainっぽいのを選ぶ
user, const mainKey = keys.find(x => {
key: keys[0], try {
}; const url = new URL(x.keyId);
const path = url.pathname.split('/').pop()?.toLowerCase();
if (url.hash) {
if (url.hash.toLowerCase().includes('main')) {
return true;
}
} else if (path?.includes('main') || path === 'publickey') {
return true;
}
} catch { /* noop */ }
return false;
});
return { user, key: mainKey ?? keys[0] };
} }
const exactKey = keys.find(x => x.keyId === keyId); const exactKey = keys.find(x => x.keyId === keyId);
if (exactKey) { if (exactKey) return { user, key: exactKey };
return {
user, // keyIdで見つからない場合、lastFetchedAtでの更新制限を弱めて再取得
key: exactKey, if (user.lastFetchedAt == null || user.lastFetchedAt < new Date(Date.now() - 1000 * 60 * 12)) {
}; const renewed = await this.apPersonService.fetchPersonWithRenewal(uri, 0);
if (renewed == null || renewed.isDeleted) return null;
this.refreshCacheByUserId(user.id);
const keys = await this.getPublicKeyByUserId(user.id);
if (keys == null || !Array.isArray(keys)) return null;
const exactKey = keys.find(x => x.keyId === keyId);
if (exactKey) return { user, key: exactKey };
} }
// 公開鍵は複数あるが、mainっぽいのを選ぶ return { user, key: null };
const mainKey = keys.find(x => { }
try {
if (x.keyId === keyId) return true;
const url = new URL(x.keyId);
const path = url.pathname.split('/').pop()?.toLowerCase();
if (url.hash) {
if (url.hash.toLowerCase().includes('main')) {
return true;
}
} else if (path?.includes('main') || path === 'publickey') {
return true;
}
} catch { /* noop */ }
return false; @bindThis
}); public async getPublicKeyByUserId(userId: MiUser['id']): Promise<MiUserPublickey[] | null> {
return { return await this.publicKeyByUserIdCache.fetch(
user, userId,
key: mainKey ?? keys[0], () => this.userPublickeysRepository.find({ where: { userId } }),
}; v => v != null,
);
} }
@bindThis @bindThis

View File

@ -250,18 +250,17 @@ export class ApPersonService implements OnModuleInit {
} }
@bindThis @bindThis
async fetchPersonWithRenewal(uri: string): Promise<MiLocalUser | MiRemoteUser | null> { async fetchPersonWithRenewal(uri: string, TTL = REMOTE_USER_CACHE_TTL): Promise<MiLocalUser | MiRemoteUser | null> {
const exist = await this.fetchPerson(uri); const exist = await this.fetchPerson(uri);
if (exist == null) return null; if (exist == null) return null;
// ついでにリモートユーザーの情報が古かったら更新しておく
if (this.userEntityService.isRemoteUser(exist)) { if (this.userEntityService.isRemoteUser(exist)) {
if (exist.lastFetchedAt == null || Date.now() - exist.lastFetchedAt.getTime() > REMOTE_USER_CACHE_TTL) { if (TTL === 0 || exist.lastFetchedAt == null || Date.now() - exist.lastFetchedAt.getTime() > TTL) {
this.logger.debug('fetchPersonWithRenewal: renew', { uri, lastFetchedAt: exist.lastFetchedAt }); this.logger.debug('fetchPersonWithRenewal: renew', { uri, TTL, lastFetchedAt: exist.lastFetchedAt });
await this.updatePerson(exist.uri); await this.updatePerson(exist.uri);
return await this.fetchPerson(uri); return await this.fetchPerson(uri);
} }
this.logger.debug('fetchPersonWithRenewal: use cache', { uri, lastFetchedAt: exist.lastFetchedAt }); this.logger.debug('fetchPersonWithRenewal: use cache', { uri, TTL, lastFetchedAt: exist.lastFetchedAt });
} }
return exist; return exist;