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
* @param uri AP Actor id
* @param keyId Key id to find. If not specified, main key will be selected.
*/
@bindThis
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;
if (user.isDeleted) return null;
const keys = await this.publicKeyByUserIdCache.fetch(
user.id,
() => this.userPublickeysRepository.find({ where: { userId: user.id } }),
v => v != null,
);
const keys = await this.getPublicKeyByUserId(user.id);
if (keys == null || !Array.isArray(keys)) return null;
if (keys == null || !Array.isArray(keys)) return { user, key: null };
if (keys.length === 0) {
return {
user,
key: keys[0],
};
if (!keyId) {
// mainっぽいのを選ぶ
const mainKey = keys.find(x => {
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);
if (exactKey) {
return {
user,
key: exactKey,
};
if (exactKey) return { user, key: exactKey };
// keyIdで見つからない場合、lastFetchedAtでの更新制限を弱めて再取得
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っぽいのを選ぶ
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 { user, key: null };
}
return false;
});
return {
user,
key: mainKey ?? keys[0],
};
@bindThis
public async getPublicKeyByUserId(userId: MiUser['id']): Promise<MiUserPublickey[] | null> {
return await this.publicKeyByUserIdCache.fetch(
userId,
() => this.userPublickeysRepository.find({ where: { userId } }),
v => v != null,
);
}
@bindThis

View File

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