calckey/packages/backend/src/remote/resolve-user.ts

112 lines
3.4 KiB
TypeScript
Raw Normal View History

import { URL } from 'node:url';
import webFinger from './webfinger.js';
import config from '@/config/index.js';
import { createPerson, updatePerson } from './activitypub/models/person.js';
import { remoteLogger } from './logger.js';
import chalk from 'chalk';
import { User, IRemoteUser } from '@/models/entities/user.js';
import { Users } from '@/models/index.js';
import { toPuny } from '@/misc/convert-host.js';
import { IsNull } from 'typeorm';
2018-03-31 10:55:00 +00:00
2019-02-02 19:04:57 +00:00
const logger = remoteLogger.createSubLogger('resolve-user');
export async function resolveUser(username: string, host: string | null): Promise<User> {
2018-03-31 10:55:00 +00:00
const usernameLower = username.toLowerCase();
2018-05-06 19:26:45 +00:00
2019-04-09 15:59:41 +00:00
if (host == null) {
2019-02-02 19:04:57 +00:00
logger.info(`return local user: ${usernameLower}`);
return await Users.findOneBy({ usernameLower, host: IsNull() }).then(u => {
if (u == null) {
2019-04-13 19:17:24 +00:00
throw new Error('user not found');
} else {
return u;
}
});
2018-05-06 19:26:45 +00:00
}
host = toPuny(host);
2022-02-28 16:24:50 +00:00
if (config.host === host) {
2019-02-02 19:04:57 +00:00
logger.info(`return local user: ${usernameLower}`);
return await Users.findOneBy({ usernameLower, host: IsNull() }).then(u => {
if (u == null) {
2019-04-13 19:17:24 +00:00
throw new Error('user not found');
} else {
return u;
}
});
2018-04-08 06:25:17 +00:00
}
const user = await Users.findOneBy({ usernameLower, host }) as IRemoteUser | null;
2019-04-09 15:59:41 +00:00
const acctLower = `${usernameLower}@${host}`;
2018-03-31 10:55:00 +00:00
Use PostgreSQL instead of MongoDB (#4572) * wip * Update note.ts * Update timeline.ts * Update core.ts * wip * Update generate-visibility-query.ts * wip * wip * wip * wip * wip * Update global-timeline.ts * wip * wip * wip * Update vote.ts * wip * wip * Update create.ts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update files.ts * wip * wip * Update CONTRIBUTING.md * wip * wip * wip * wip * wip * wip * wip * wip * Update read-notification.ts * wip * wip * wip * wip * wip * wip * wip * Update cancel.ts * wip * wip * wip * Update show.ts * wip * wip * Update gen-id.ts * Update create.ts * Update id.ts * wip * wip * wip * wip * wip * wip * wip * Docker: Update files about Docker (#4599) * Docker: Use cache if files used by `yarn install` was not updated This patch reduces the number of times to installing node_modules. For example, `yarn install` step will be skipped when only ".config/default.yml" is updated. * Docker: Migrate MongoDB to Postgresql Misskey uses Postgresql as a database instead of Mongodb since version 11. * Docker: Uncomment about data persistence This patch will save a lot of databases. * wip * wip * wip * Update activitypub.ts * wip * wip * wip * Update logs.ts * wip * Update drive-file.ts * Update register.ts * wip * wip * Update mentions.ts * wip * wip * wip * Update recommendation.ts * wip * Update index.ts * wip * Update recommendation.ts * Doc: Update docker.ja.md and docker.en.md (#1) (#4608) Update how to set up misskey. * wip * :v: * wip * Update note.ts * Update postgre.ts * wip * wip * wip * wip * Update add-file.ts * wip * wip * wip * Clean up * Update logs.ts * wip * :pizza: * wip * Ad notes * wip * Update api-visibility.ts * Update note.ts * Update add-file.ts * tests * tests * Update postgre.ts * Update utils.ts * wip * wip * Refactor * wip * Refactor * wip * wip * Update show-users.ts * Update update-instance.ts * wip * Update feed.ts * Update outbox.ts * Update outbox.ts * Update user.ts * wip * Update list.ts * Update update-hashtag.ts * wip * Update update-hashtag.ts * Refactor * Update update.ts * wip * wip * :v: * clean up * docs * Update push.ts * wip * Update api.ts * wip * :v: * Update make-pagination-query.ts * :v: * Delete hashtags.ts * Update instances.ts * Update instances.ts * Update create.ts * Update search.ts * Update reversi-game.ts * Update signup.ts * Update user.ts * id * Update example.yml * :art: * objectid * fix * reversi * reversi * Fix bug of chart engine * Add test of chart engine * Improve test * Better testing * Improve chart engine * Refactor * Add test of chart engine * Refactor * Add chart test * Fix bug * コミットし忘れ * Refactoring * :v: * Add tests * Add test * Extarct note tests * Refactor * 存在しないユーザーにメンションできなくなっていた問題を修正 * Fix bug * Update update-meta.ts * Fix bug * Update mention.vue * Fix bug * Update meta.ts * Update CONTRIBUTING.md * Fix bug * Fix bug * Fix bug * Clean up * Clean up * Update notification.ts * Clean up * Add mute tests * Add test * Refactor * Add test * Fix test * Refactor * Refactor * Add tests * Update utils.ts * Update utils.ts * Fix test * Update package.json * Update update.ts * Update manifest.ts * Fix bug * Fix bug * Add test * :art: * Update endpoint permissions * Updaye permisison * Update person.ts #4299 * データベースと同期しないように * Fix bug * Fix bug * Update reversi-game.ts * Use a feature of Node v11.7.0 to extract a public key (#4644) * wip * wip * :v: * Refactoring #1540 * test * test * test * test * test * test * test * Fix bug * Fix test * :sushi: * wip * #4471 * Add test for #4335 * Refactor * Fix test * Add tests * :clock4: * Fix bug * Add test * Add test * rename * Fix bug
2019-04-07 12:50:36 +00:00
if (user == null) {
const self = await resolveSelf(acctLower);
2019-02-02 19:43:43 +00:00
logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`);
return await createPerson(self.href);
}
// ユーザー情報が古い場合は、WebFilgerからやりなおして返す
if (user.lastFetchedAt == null || Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24) {
// 繋がらないインスタンスに何回も試行するのを防ぐ, 後続の同様処理の連続試行を防ぐ ため 試行前にも更新する
await Users.update(user.id, {
lastFetchedAt: new Date(),
});
2019-02-02 19:04:57 +00:00
logger.info(`try resync: ${acctLower}`);
const self = await resolveSelf(acctLower);
if (user.uri !== self.href) {
// if uri mismatch, Fix (user@host <=> AP's Person id(IRemoteUser.uri)) mapping.
2019-02-02 19:04:57 +00:00
logger.info(`uri missmatch: ${acctLower}`);
logger.info(`recovery missmatch uri for (username=${username}, host=${host}) from ${user.uri} to ${self.href}`);
2018-03-31 10:55:00 +00:00
// validate uri
const uri = new URL(self.href);
2019-04-09 15:59:41 +00:00
if (uri.hostname !== host) {
throw new Error(`Invalid uri`);
}
Use PostgreSQL instead of MongoDB (#4572) * wip * Update note.ts * Update timeline.ts * Update core.ts * wip * Update generate-visibility-query.ts * wip * wip * wip * wip * wip * Update global-timeline.ts * wip * wip * wip * Update vote.ts * wip * wip * Update create.ts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update files.ts * wip * wip * Update CONTRIBUTING.md * wip * wip * wip * wip * wip * wip * wip * wip * Update read-notification.ts * wip * wip * wip * wip * wip * wip * wip * Update cancel.ts * wip * wip * wip * Update show.ts * wip * wip * Update gen-id.ts * Update create.ts * Update id.ts * wip * wip * wip * wip * wip * wip * wip * Docker: Update files about Docker (#4599) * Docker: Use cache if files used by `yarn install` was not updated This patch reduces the number of times to installing node_modules. For example, `yarn install` step will be skipped when only ".config/default.yml" is updated. * Docker: Migrate MongoDB to Postgresql Misskey uses Postgresql as a database instead of Mongodb since version 11. * Docker: Uncomment about data persistence This patch will save a lot of databases. * wip * wip * wip * Update activitypub.ts * wip * wip * wip * Update logs.ts * wip * Update drive-file.ts * Update register.ts * wip * wip * Update mentions.ts * wip * wip * wip * Update recommendation.ts * wip * Update index.ts * wip * Update recommendation.ts * Doc: Update docker.ja.md and docker.en.md (#1) (#4608) Update how to set up misskey. * wip * :v: * wip * Update note.ts * Update postgre.ts * wip * wip * wip * wip * Update add-file.ts * wip * wip * wip * Clean up * Update logs.ts * wip * :pizza: * wip * Ad notes * wip * Update api-visibility.ts * Update note.ts * Update add-file.ts * tests * tests * Update postgre.ts * Update utils.ts * wip * wip * Refactor * wip * Refactor * wip * wip * Update show-users.ts * Update update-instance.ts * wip * Update feed.ts * Update outbox.ts * Update outbox.ts * Update user.ts * wip * Update list.ts * Update update-hashtag.ts * wip * Update update-hashtag.ts * Refactor * Update update.ts * wip * wip * :v: * clean up * docs * Update push.ts * wip * Update api.ts * wip * :v: * Update make-pagination-query.ts * :v: * Delete hashtags.ts * Update instances.ts * Update instances.ts * Update create.ts * Update search.ts * Update reversi-game.ts * Update signup.ts * Update user.ts * id * Update example.yml * :art: * objectid * fix * reversi * reversi * Fix bug of chart engine * Add test of chart engine * Improve test * Better testing * Improve chart engine * Refactor * Add test of chart engine * Refactor * Add chart test * Fix bug * コミットし忘れ * Refactoring * :v: * Add tests * Add test * Extarct note tests * Refactor * 存在しないユーザーにメンションできなくなっていた問題を修正 * Fix bug * Update update-meta.ts * Fix bug * Update mention.vue * Fix bug * Update meta.ts * Update CONTRIBUTING.md * Fix bug * Fix bug * Fix bug * Clean up * Clean up * Update notification.ts * Clean up * Add mute tests * Add test * Refactor * Add test * Fix test * Refactor * Refactor * Add tests * Update utils.ts * Update utils.ts * Fix test * Update package.json * Update update.ts * Update manifest.ts * Fix bug * Fix bug * Add test * :art: * Update endpoint permissions * Updaye permisison * Update person.ts #4299 * データベースと同期しないように * Fix bug * Fix bug * Update reversi-game.ts * Use a feature of Node v11.7.0 to extract a public key (#4644) * wip * wip * :v: * Refactoring #1540 * test * test * test * test * test * test * test * Fix bug * Fix test * :sushi: * wip * #4471 * Add test for #4335 * Refactor * Fix test * Add tests * :clock4: * Fix bug * Add test * Add test * rename * Fix bug
2019-04-07 12:50:36 +00:00
await Users.update({
usernameLower,
2021-12-09 14:58:30 +00:00
host: host,
2019-02-02 04:57:26 +00:00
}, {
2021-12-09 14:58:30 +00:00
uri: self.href,
});
} else {
2019-02-02 19:04:57 +00:00
logger.info(`uri is fine: ${acctLower}`);
2018-03-31 10:55:00 +00:00
}
await updatePerson(self.href);
2019-02-02 19:04:57 +00:00
logger.info(`return resynced remote user: ${acctLower}`);
return await Users.findOneBy({ uri: self.href }).then(u => {
if (u == null) {
2019-04-13 19:17:24 +00:00
throw new Error('user not found');
} else {
return u;
}
});
2019-02-02 19:43:43 +00:00
}
2018-03-31 10:55:00 +00:00
2019-02-02 19:43:43 +00:00
logger.info(`return existing remote user: ${acctLower}`);
2018-03-31 10:55:00 +00:00
return user;
2019-04-07 14:06:07 +00:00
}
async function resolveSelf(acctLower: string) {
2019-02-02 19:43:43 +00:00
logger.info(`WebFinger for ${chalk.yellow(acctLower)}`);
2019-02-04 00:02:23 +00:00
const finger = await webFinger(acctLower).catch(e => {
logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${ e.statusCode || e.message }`);
throw new Error(`Failed to WebFinger for ${acctLower}: ${ e.statusCode || e.message }`);
2019-02-04 00:02:23 +00:00
});
const self = finger.links.find(link => link.rel != null && link.rel.toLowerCase() === 'self');
if (!self) {
2019-02-04 00:06:13 +00:00
logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: self link not found`);
throw new Error('self link not found');
}
return self;
}