firefish/packages/backend/src/remote/activitypub/models/person.ts

728 lines
19 KiB
TypeScript
Raw Normal View History

2023-01-13 04:40:33 +00:00
import { URL } from "node:url";
import promiseLimit from "promise-limit";
import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js";
2023-01-13 04:40:33 +00:00
import type { Note } from "@/models/entities/note.js";
import { updateUsertags } from "@/services/update-hashtag.js";
2023-01-13 04:40:33 +00:00
import {
Users,
2023-11-26 20:33:46 +00:00
Instances,
Followings,
2023-01-13 04:40:33 +00:00
UserProfiles,
UserPublickeys,
DriveFiles,
2023-01-13 04:40:33 +00:00
} from "@/models/index.js";
import type { IRemoteUser, CacheableUser } from "@/models/entities/user.js";
import { User } from "@/models/entities/user.js";
import type { Emoji } from "@/models/entities/emoji.js";
import { UserNotePining } from "@/models/entities/user-note-pining.js";
import { genId } from "backend-rs";
import { UserPublickey } from "@/models/entities/user-publickey.js";
import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
import { isSameOrigin, toPuny } from "backend-rs";
import { UserProfile } from "@/models/entities/user-profile.js";
import { toArray } from "@/prelude/array.js";
2023-01-13 04:40:33 +00:00
import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
import { normalizeForSearch } from "@/misc/normalize-for-search.js";
import { truncate } from "@/misc/truncate.js";
import { StatusError } from "@/misc/fetch.js";
2023-11-26 20:33:46 +00:00
import { uriPersonCache } from "@/services/user-cache.js";
import { publishInternalEvent } from "@/services/stream.js";
import { db } from "@/db/postgre.js";
2023-01-13 04:40:33 +00:00
import { apLogger } from "../logger.js";
import { htmlToMfm } from "../misc/html-to-mfm.js";
import { fromHtml } from "@/mfm/from-html.js";
import type { IActor, IObject } from "../type.js";
2023-01-13 04:40:33 +00:00
import {
isCollectionOrOrderedCollection,
isCollection,
2023-01-13 04:40:33 +00:00
getApId,
2023-11-26 20:33:46 +00:00
getOneApHrefNullable,
isPropertyValue,
getApType,
isActor,
2023-01-13 04:40:33 +00:00
} from "../type.js";
import Resolver from "../resolver.js";
2023-11-26 20:33:46 +00:00
import { extractApHashtags } from "./tag.js";
import { resolveNote, extractEmojis } from "./note.js";
import { resolveImage } from "./image.js";
import { inspect } from "node:util";
2019-02-03 07:45:13 +00:00
const logger = apLogger;
2018-04-08 19:08:56 +00:00
const nameLength = 128;
const summaryLength = 2048;
2018-08-29 07:10:03 +00:00
/**
* Validate and convert to actor object
* @param x Fetched object
2018-08-29 07:10:03 +00:00
* @param uri Fetch target URI
*/
function validateActor(x: IObject, uri: string): IActor {
2019-04-09 15:59:41 +00:00
const expectHost = toPuny(new URL(uri).hostname);
2018-08-29 07:10:03 +00:00
2018-07-26 08:13:55 +00:00
if (x == null) {
2023-01-13 04:40:33 +00:00
throw new Error("invalid Actor: object is null");
2018-07-26 08:13:55 +00:00
}
if (!isActor(x)) {
throw new Error(`invalid Actor type '${x.type}'`);
2018-07-26 08:13:55 +00:00
}
2023-01-13 04:40:33 +00:00
if (!(typeof x.id === "string" && x.id.length > 0)) {
throw new Error("invalid Actor: wrong id");
2022-04-17 11:58:37 +00:00
}
2023-01-13 04:40:33 +00:00
if (!(typeof x.inbox === "string" && x.inbox.length > 0)) {
throw new Error("invalid Actor: wrong inbox");
2022-04-17 11:58:37 +00:00
}
2018-07-26 08:13:55 +00:00
2023-01-13 04:40:33 +00:00
if (
!(
typeof x.preferredUsername === "string" &&
x.preferredUsername.length > 0 &&
x.preferredUsername.length <= 128 &&
/^\w([\w-.]*\w)?$/.test(x.preferredUsername)
)
) {
throw new Error("invalid Actor: wrong username");
2022-04-17 11:58:37 +00:00
}
// These fields are only informational, and some AP software allows these
// fields to be very long. If they are too long, we cut them off. This way
// we can at least see these users and their activities.
2022-04-17 11:58:37 +00:00
if (x.name) {
2023-01-13 04:40:33 +00:00
if (!(typeof x.name === "string" && x.name.length > 0)) {
throw new Error("invalid Actor: wrong name");
2022-04-17 11:58:37 +00:00
}
x.name = truncate(x.name, nameLength);
}
if (x.summary) {
2023-01-13 04:40:33 +00:00
if (!(typeof x.summary === "string" && x.summary.length > 0)) {
throw new Error("invalid Actor: wrong summary");
2022-04-17 11:58:37 +00:00
}
x.summary = truncate(x.summary, summaryLength);
}
2018-07-26 08:13:55 +00:00
const idHost = toPuny(new URL(x.id!).hostname);
2018-08-29 07:10:03 +00:00
if (idHost !== expectHost) {
2023-01-13 04:40:33 +00:00
throw new Error("invalid Actor: id has different host");
2018-08-29 07:10:03 +00:00
}
if (x.publicKey) {
2023-01-13 04:40:33 +00:00
if (typeof x.publicKey.id !== "string") {
throw new Error("invalid Actor: publicKey.id is not a string");
}
2018-08-29 07:10:03 +00:00
const publicKeyIdHost = toPuny(new URL(x.publicKey.id).hostname);
if (publicKeyIdHost !== expectHost) {
2023-01-13 04:40:33 +00:00
throw new Error("invalid Actor: publicKey.id has different host");
}
2018-08-29 07:10:03 +00:00
}
return x;
2018-07-26 08:13:55 +00:00
}
2018-04-08 19:08:56 +00:00
/**
2022-12-16 00:09:00 +00:00
* Fetch a Person.
*
2023-07-02 22:18:30 +00:00
* If the target Person is registered in Firefish, it will be returned.
2022-12-16 00:09:00 +00:00
*/
2023-01-13 04:40:33 +00:00
export async function fetchPerson(
uri: string,
resolver?: Resolver,
): Promise<CacheableUser | null> {
if (typeof uri !== "string") throw new Error("uri is not string");
2018-04-08 19:08:56 +00:00
2023-07-03 02:10:33 +00:00
const cached = await uriPersonCache.get(uri, true);
if (cached) return cached;
// Fetch from the database if the URI points to this server
if (isSameOrigin(uri)) {
2023-01-13 04:40:33 +00:00
const id = uri.split("/").pop();
const u = await Users.findOneBy({ id });
2023-07-03 00:37:46 +00:00
if (u) await uriPersonCache.set(uri, u);
return u;
2018-04-08 19:08:56 +00:00
}
//#region Returns if already registered with this server
const user = await Users.findOneBy({ uri });
2018-04-08 19:08:56 +00:00
if (user != null) {
await uriPersonCache.set(uri, user);
return user;
2018-04-08 19:08:56 +00:00
}
//#endregion
return null;
}
/**
* Create Person.
2018-04-08 19:08:56 +00:00
*/
2023-01-13 04:40:33 +00:00
export async function createPerson(
uri: string,
resolver?: Resolver,
): Promise<User> {
if (isSameOrigin(uri)) {
2023-01-13 04:40:33 +00:00
throw new StatusError(
"cannot resolve local user",
400,
"cannot resolve local user",
);
}
2018-04-08 19:08:56 +00:00
if (resolver == null) resolver = new Resolver();
2023-01-13 04:40:33 +00:00
const object = (await resolver.resolve(uri)) as any;
2018-04-08 19:08:56 +00:00
const person = validateActor(object, uri);
2018-04-08 19:08:56 +00:00
2019-02-03 07:45:13 +00:00
logger.info(`Creating the Person: ${person.id}`);
2018-04-08 19:08:56 +00:00
const host = toPuny(new URL(object.id).hostname);
2018-04-08 19:08:56 +00:00
2023-10-16 17:05:32 +00:00
const fields = analyzeAttachments(person.attachment || []);
2018-12-11 11:18:12 +00:00
2023-01-13 04:40:33 +00:00
const tags = extractApHashtags(person.tag)
.map((tag) => normalizeForSearch(tag))
.splice(0, 32);
2023-05-03 19:50:43 +00:00
const isBot = getApType(object) !== "Person";
2018-06-23 10:18:14 +00:00
2023-01-13 04:40:33 +00:00
const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
2023-02-10 19:14:33 +00:00
const url = getOneApHrefNullable(person.url);
2023-02-10 23:41:19 +00:00
if (url && !url.startsWith("https://")) {
throw new Error(`unexpected schema of person url: ${url}`);
2023-02-10 19:14:33 +00:00
}
let followersCount: number | undefined;
if (typeof person.followers === "string") {
try {
const data = await fetch(person.followers, {
2023-03-31 02:10:03 +00:00
headers: { Accept: "application/json" },
});
const json_data = JSON.parse(await data.text());
followersCount = json_data.totalItems;
} catch {
followersCount = undefined;
}
}
let followingCount: number | undefined;
if (typeof person.following === "string") {
try {
const data = await fetch(person.following, {
2023-03-31 02:10:03 +00:00
headers: { Accept: "application/json" },
});
const json_data = JSON.parse(await data.text());
followingCount = json_data.totalItems;
} catch (e) {
followingCount = undefined;
}
}
let notesCount: number | undefined;
if (typeof person.outbox === "string") {
try {
const data = await fetch(person.outbox, {
headers: { Accept: "application/json" },
});
const json_data = JSON.parse(await data.text());
notesCount = json_data.totalItems;
} catch (e) {
notesCount = undefined;
}
}
2018-04-08 19:08:56 +00:00
// Create user
2018-04-19 09:58:57 +00:00
let user: IRemoteUser;
try {
// Start transaction
2023-01-13 04:40:33 +00:00
await db.transaction(async (transactionalEntityManager) => {
user = (await transactionalEntityManager.save(
new User({
id: genId(),
avatarId: null,
bannerId: null,
createdAt: new Date(),
lastFetchedAt: new Date(),
name: truncate(person.name, nameLength),
isLocked: !!person.manuallyApprovesFollowers,
movedToUri: person.movedTo,
alsoKnownAs: person.alsoKnownAs,
isExplorable: !!person.discoverable,
username: person.preferredUsername,
usernameLower: person.preferredUsername!.toLowerCase(),
host,
inbox: person.inbox,
sharedInbox:
person.sharedInbox ||
(person.endpoints ? person.endpoints.sharedInbox : undefined),
followersUri: person.followers
? getApId(person.followers)
: undefined,
2023-03-31 02:10:03 +00:00
followersCount:
followersCount !== undefined
? followersCount
: person.followers &&
typeof person.followers !== "string" &&
isCollectionOrOrderedCollection(person.followers)
? person.followers.totalItems
: undefined,
2023-03-31 02:10:03 +00:00
followingCount:
followingCount !== undefined
? followingCount
: person.following &&
typeof person.following !== "string" &&
isCollectionOrOrderedCollection(person.following)
? person.following.totalItems
: undefined,
notesCount:
notesCount !== undefined
? notesCount
: person.outbox &&
typeof person.outbox !== "string" &&
isCollectionOrOrderedCollection(person.outbox)
? person.outbox.totalItems
: undefined,
2023-01-13 04:40:33 +00:00
featured: person.featured ? getApId(person.featured) : undefined,
uri: person.id,
tags,
isBot,
isCat: (person as any).isCat === true,
speakAsCat:
person.speakAsCat != null
? person.speakAsCat === true
: (person as any).isCat === true,
isIndexable: person.indexable,
2023-01-13 04:40:33 +00:00
}),
)) as IRemoteUser;
await transactionalEntityManager.save(
new UserProfile({
userId: user.id,
description: person._misskey_summary
? truncate(person._misskey_summary, summaryLength)
: person.summary
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
: null,
2023-02-10 19:14:33 +00:00
url: url,
2023-01-13 04:40:33 +00:00
fields,
birthday: bday ? bday[0] : null,
location: person["vcard:Address"] || null,
userHost: host,
}),
);
if (person.publicKey) {
2023-01-13 04:40:33 +00:00
await transactionalEntityManager.save(
new UserPublickey({
userId: user.id,
keyId: person.publicKey.id,
keyPem: person.publicKey.publicKeyPem,
}),
);
}
});
2018-04-19 09:58:57 +00:00
} catch (e) {
// duplicate key error
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 (isDuplicateKeyValueError(e)) {
// /users/@a => /users/:id Corresponds to an error that may occur when the input is an alias like
const u = await Users.findOneBy({
2021-11-13 10:10:14 +00:00
uri: person.id,
});
2018-04-19 09:58:57 +00:00
if (u) {
user = u as IRemoteUser;
} else {
2023-01-13 04:40:33 +00:00
throw new Error("already registered");
}
} else {
logger.error(inspect(e));
throw e;
}
2018-04-19 09:58:57 +00:00
}
2018-04-08 19:08:56 +00:00
2018-10-23 21:17:55 +00:00
// Register host
2023-01-13 04:40:33 +00:00
registerOrFetchInstanceDoc(host).then((i) => {
Instances.increment({ id: i.id }, "usersCount", 1);
fetchInstanceMetadata(i);
2018-10-23 21:17:55 +00:00
});
// Hashtag update
updateUsertags(user!, tags);
//#region Fetch avatar and header image
2023-01-13 04:40:33 +00:00
const [avatar, banner] = await Promise.all(
[person.icon, person.image].map((img, index) =>
2023-01-13 04:40:33 +00:00
img == null
? Promise.resolve(null)
2024-04-19 04:54:11 +00:00
: resolveImage(
user,
img,
index === 0 ? "userAvatar" : index === 1 ? "userBanner" : null,
2024-04-19 04:54:11 +00:00
).catch(() => null),
2023-01-13 04:40:33 +00:00
),
);
2018-06-09 23:41:57 +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
const avatarId = avatar ? avatar.id : null;
const bannerId = banner ? banner.id : null;
await Users.update(user!.id, {
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
avatarId,
bannerId,
2018-06-09 23:41:57 +00:00
});
2018-04-08 19:08:56 +00:00
user!.avatarId = avatarId;
user!.bannerId = bannerId;
2018-04-08 19:08:56 +00:00
//#endregion
//#region Get custom emoji
2023-01-13 04:40:33 +00:00
const emojis = await extractEmojis(person.tag || [], host).catch((e) => {
logger.info(`extractEmojis:\n${inspect(e)}`);
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
return [] as Emoji[];
});
2023-01-13 04:40:33 +00:00
const emojiNames = emojis.map((emoji) => emoji.name);
await Users.update(user!.id, {
2021-11-13 10:10:14 +00:00
emojis: emojiNames,
});
//#endregion
await updateFeatured(user!.id, resolver).catch((err) =>
logger.error(inspect(err)),
);
2018-10-23 21:17:55 +00:00
return user!;
2018-04-08 19:08:56 +00:00
}
2018-04-17 06:30:58 +00:00
/**
2022-12-07 17:16:23 +00:00
* Update Person data from remote.
2023-07-02 22:18:30 +00:00
* If the target Person is not registered in Firefish, it is ignored.
2018-09-01 08:53:38 +00:00
* @param uri URI of Person
* @param resolver Resolver
2022-12-07 17:16:23 +00:00
* @param hint Hint of Person object (If this value is a valid Person, it is used for updating without Remote resolve)
2018-04-17 06:30:58 +00:00
*/
2023-01-13 04:40:33 +00:00
export async function updatePerson(
uri: string,
resolver?: Resolver | null,
hint?: IObject,
): Promise<void> {
if (typeof uri !== "string") throw new Error("uri is not string");
2018-04-17 06:30:58 +00:00
2022-12-07 17:16:23 +00:00
// Skip if the URI points to this server
if (isSameOrigin(uri)) {
2018-04-17 06:30:58 +00:00
return;
}
2022-12-07 17:16:23 +00:00
//#region Already registered on this server?
const user = (await Users.findOneBy({ uri })) as IRemoteUser;
2018-04-17 06:30:58 +00:00
if (user == null) {
2018-04-17 06:30:58 +00:00
return;
}
//#endregion
if (resolver == null) resolver = new Resolver();
2023-01-13 04:40:33 +00:00
const object = hint || (await resolver.resolve(uri));
2018-04-17 06:30:58 +00:00
const person = validateActor(object, uri);
2018-04-17 06:30:58 +00:00
2019-02-03 07:45:13 +00:00
logger.info(`Updating the Person: ${person.id}`);
2018-04-17 06:30:58 +00:00
2022-12-07 17:16:23 +00:00
// Fetch avatar and header image
2023-01-13 04:40:33 +00:00
const [avatar, banner] = await Promise.all(
[person.icon, person.image].map((img, index) =>
2023-01-13 04:40:33 +00:00
img == null
? Promise.resolve(null)
2024-04-19 04:54:11 +00:00
: resolveImage(
user,
img,
index === 0 ? "userAvatar" : index === 1 ? "userBanner" : null,
2024-04-19 04:54:11 +00:00
).catch(() => null),
2023-01-13 04:40:33 +00:00
),
);
2018-04-17 06:30:58 +00:00
2022-12-07 17:16:23 +00:00
// Custom pictogram acquisition
const emojis = await extractEmojis(person.tag || [], user.host).catch((e) => {
logger.info(`extractEmojis:\n${inspect(e)}`);
return [] as Emoji[];
});
2023-01-13 04:40:33 +00:00
const emojiNames = emojis.map((emoji) => emoji.name);
2023-10-23 09:32:33 +00:00
const fields = analyzeAttachments(person.attachment || []);
2018-12-11 11:18:12 +00:00
2023-01-13 04:40:33 +00:00
const tags = extractApHashtags(person.tag)
.map((tag) => normalizeForSearch(tag))
.splice(0, 32);
2023-01-13 04:40:33 +00:00
const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
2023-02-10 19:14:33 +00:00
const url = getOneApHrefNullable(person.url);
2023-02-10 23:41:19 +00:00
if (url && !url.startsWith("https://")) {
throw new Error(`unexpected schema of person url: ${url}`);
}
let followersCount: number | undefined;
if (typeof person.followers === "string") {
try {
let data = await fetch(person.followers, {
2023-03-31 02:10:03 +00:00
headers: { Accept: "application/json" },
});
let json_data = JSON.parse(await data.text());
followersCount = json_data.totalItems;
} catch {
followersCount = undefined;
}
}
let followingCount: number | undefined;
if (typeof person.following === "string") {
try {
let data = await fetch(person.following, {
2023-03-31 02:10:03 +00:00
headers: { Accept: "application/json" },
});
let json_data = JSON.parse(await data.text());
followingCount = json_data.totalItems;
} catch {
followingCount = undefined;
}
2023-02-10 19:14:33 +00:00
}
let notesCount: number | undefined;
if (typeof person.outbox === "string") {
try {
let data = await fetch(person.outbox, {
headers: { Accept: "application/json" },
});
let json_data = JSON.parse(await data.text());
notesCount = json_data.totalItems;
} catch (e) {
notesCount = undefined;
}
}
2019-01-21 02:15:36 +00:00
const updates = {
lastFetchedAt: new Date(),
inbox: person.inbox,
2023-01-13 04:40:33 +00:00
sharedInbox:
person.sharedInbox ||
(person.endpoints ? person.endpoints.sharedInbox : undefined),
followersUri: person.followers ? getApId(person.followers) : undefined,
2023-03-31 02:10:03 +00:00
followersCount:
followersCount !== undefined
? followersCount
: person.followers &&
typeof person.followers !== "string" &&
isCollectionOrOrderedCollection(person.followers)
? person.followers.totalItems
: undefined,
2023-03-31 02:10:03 +00:00
followingCount:
followingCount !== undefined
? followingCount
: person.following &&
typeof person.following !== "string" &&
isCollectionOrOrderedCollection(person.following)
? person.following.totalItems
: undefined,
notesCount:
notesCount !== undefined
? notesCount
: person.outbox &&
typeof person.outbox !== "string" &&
isCollectionOrOrderedCollection(person.outbox)
? person.outbox.totalItems
: undefined,
2019-01-21 02:15:36 +00:00
featured: person.featured,
emojis: emojiNames,
2021-08-17 08:25:19 +00:00
name: truncate(person.name, nameLength),
tags,
2023-05-03 19:50:43 +00:00
isBot: getApType(object) !== "Person",
2019-01-21 02:15:36 +00:00
isCat: (person as any).isCat === true,
speakAsCat:
person.speakAsCat != null
? person.speakAsCat === true
: (person as any).isCat === true,
isIndexable: person.indexable,
2019-10-15 19:03:51 +00:00
isLocked: !!person.manuallyApprovesFollowers,
movedToUri: person.movedTo || null,
alsoKnownAs: person.alsoKnownAs || null,
isExplorable: !!person.discoverable,
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
} as Partial<User>;
2019-01-21 02:15:36 +00:00
if (avatar) {
if (user?.avatarId)
2024-04-19 04:54:11 +00:00
await DriveFiles.update(user.avatarId, { usageHint: null });
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
updates.avatarId = avatar.id;
2019-01-21 02:15:36 +00:00
}
if (banner) {
if (user?.bannerId)
2024-04-19 04:54:11 +00:00
await DriveFiles.update(user.bannerId, { usageHint: null });
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
updates.bannerId = banner.id;
2019-01-21 02:15:36 +00:00
}
2018-04-17 06:30:58 +00:00
// Update user
await Users.update(user.id, updates);
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 (person.publicKey) {
2023-01-13 04:40:33 +00:00
await UserPublickeys.update(
{ userId: user.id },
2023-01-13 04:40:33 +00:00
{
keyId: person.publicKey.id,
keyPem: person.publicKey.publicKeyPem,
},
);
}
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
2023-01-13 04:40:33 +00:00
await UserProfiles.update(
{ userId: user.id },
2023-01-13 04:40:33 +00:00
{
2023-02-10 19:14:33 +00:00
url: url,
2023-01-13 04:40:33 +00:00
fields,
description: person._misskey_summary
? truncate(person._misskey_summary, summaryLength)
: person.summary
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
: null,
2023-01-13 04:40:33 +00:00
birthday: bday ? bday[0] : null,
location: person["vcard:Address"] || null,
},
);
publishInternalEvent("remoteUserUpdated", { id: user.id });
2022-12-07 17:16:23 +00:00
// Hashtag Update
updateUsertags(user, tags);
2022-12-07 17:16:23 +00:00
// If the user in question is a follower, followers will also be updated.
2023-01-13 04:40:33 +00:00
await Followings.update(
{
followerId: user.id,
2023-01-13 04:40:33 +00:00
},
{
followerSharedInbox:
person.sharedInbox ||
(person.endpoints ? person.endpoints.sharedInbox : null),
2023-01-13 04:40:33 +00:00
},
);
await updateFeatured(user.id, resolver).catch((err) =>
logger.error(inspect(err)),
);
2018-04-17 06:30:58 +00:00
}
2018-04-08 19:08:56 +00:00
/**
2022-12-07 17:16:23 +00:00
* Resolve Person.
2018-04-08 19:08:56 +00:00
*
2023-07-02 22:18:30 +00:00
* If the target person is registered in Firefish, it returns it;
* otherwise, it fetches it from the remote server, registers it in Firefish, and returns it.
2018-04-08 19:08:56 +00:00
*/
2023-01-13 04:40:33 +00:00
export async function resolvePerson(
uri: string,
resolver?: Resolver,
): Promise<CacheableUser> {
if (typeof uri !== "string") throw new Error("uri is not string");
2018-04-08 19:08:56 +00:00
2022-12-07 17:16:23 +00:00
//#region If already registered on this server, return it.
const user = await fetchPerson(uri);
2018-04-08 19:08:56 +00:00
if (user != null) {
return user;
2018-04-08 19:08:56 +00:00
}
//#endregion
2022-12-07 17:16:23 +00:00
// Fetched from remote server and registered
if (resolver == null) resolver = new Resolver();
return await createPerson(uri, resolver);
}
2023-01-13 04:40:33 +00:00
export function analyzeAttachments(
attachments: IObject | IObject[] | undefined,
) {
const fields: {
2023-01-13 04:40:33 +00:00
name: string;
value: string;
}[] = [];
if (Array.isArray(attachments)) {
for (const attachment of attachments.filter(isPropertyValue)) {
2023-10-16 17:05:32 +00:00
fields.push({
name: attachment.name,
value: fromHtml(attachment.value),
});
}
}
2023-10-16 17:05:32 +00:00
return fields;
2018-12-11 11:18:12 +00:00
}
2023-01-13 04:40:33 +00:00
export async function updateFeatured(userId: User["id"], resolver?: Resolver) {
const user = await Users.findOneByOrFail({ id: userId });
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 (!Users.isRemoteUser(user)) return;
if (!user.featured) return;
2019-02-03 07:45:13 +00:00
logger.info(`Updating the featured: ${user.uri}`);
if (resolver == null) resolver = new Resolver();
// Resolve to (Ordered)Collection Object
const collection = await resolver.resolveCollection(user.featured);
2023-01-13 04:40:33 +00:00
if (!isCollectionOrOrderedCollection(collection))
throw new Error("Object is not Collection or OrderedCollection");
// Resolve to Object(may be Note) arrays
2023-01-13 04:40:33 +00:00
const unresolvedItems = isCollection(collection)
? collection.items
: collection.orderedItems;
const items = await Promise.all(
toArray(unresolvedItems).map((x) => resolver?.resolve(x)),
2023-01-13 04:40:33 +00:00
);
// Resolve and regist Notes
const limit = promiseLimit<Note | null>(2);
2023-01-13 04:40:33 +00:00
const featuredNotes = await Promise.all(
items
.filter((item) => getApType(item) === "Note") // TODO: Maybe it doesn't have to be a Note.
2024-02-15 18:59:48 +00:00
.slice(0, 15)
2023-01-13 04:40:33 +00:00
.map((item) => limit(() => resolveNote(item, resolver))),
);
await db.transaction(async (transactionalEntityManager) => {
await transactionalEntityManager.delete(UserNotePining, {
userId: user.id,
});
2021-02-17 12:34:51 +00:00
2022-12-07 17:16:23 +00:00
// For now, generate the id at a different time and maintain the order.
2021-02-17 12:34:51 +00:00
let td = 0;
2023-01-13 04:40:33 +00:00
for (const note of featuredNotes.filter((note) => note != null)) {
2021-02-17 12:34:51 +00:00
td -= 1000;
transactionalEntityManager.insert(UserNotePining, {
id: genId(new Date(Date.now() + td)),
createdAt: new Date(),
userId: user.id,
2021-11-13 10:10:14 +00:00
noteId: note!.id,
2021-02-17 12:34:51 +00:00
});
}
});
2018-04-08 19:08:56 +00:00
}