Fixed 267U.pre2

This commit is contained in:
2026-07-26 18:25:37 +09:00
parent 50bfaeafdf
commit 317d00a284
1286 changed files with 80222 additions and 1 deletions
@@ -0,0 +1,148 @@
import config from "../../config/index.js";
import { Notes, Users, UserPublickeys, MessagingMessages } from "../../models/index.js";
import { Cache } from "../../misc/cache.js";
import { uriPersonCache, userByIdCache } from "../../services/user-cache.js";
import { getApId } from "./type.js";
import { resolvePerson, updatePerson } from "./models/person.js";
import { subscriber } from "../../db/redis.js";
import { toPuny } from "../../misc/convert-host.js";
const publicKeyCache = new Cache("publicKey", 60 * 30);
const publicKeyByUserIdCache = new Cache("publicKeyByUserId", 60 * 30);
export function parseUri(value) {
const uri = getApId(value);
const parsed = new URL(uri);
if (toPuny(parsed.host) === toPuny(config.host)) {
const localRegex = new RegExp(`^.*?/(\\w+)/(\\w+)(?:/(.+))?`);
const matchLocal = uri.match(localRegex);
if (matchLocal == null) {
throw new Error(`Failed to parse local URI: ${uri}`);
}
return {
local: true,
type: matchLocal[1],
id: matchLocal[2],
rest: matchLocal[3]
};
} else {
return {
local: false,
uri
};
}
}
export default class DbResolver {
/**
* AP Note => Misskey Note in DB
*/ async getNoteFromApId(value) {
const parsed = parseUri(value);
if (parsed.local) {
if (parsed.type !== "notes") return null;
return await Notes.findOneBy({
id: parsed.id
});
} else {
return await Notes.findOne({
where: [
{
uri: parsed.uri
},
{
url: parsed.uri
}
]
});
}
}
async getMessageFromApId(value) {
const parsed = parseUri(value);
if (parsed.local) {
if (parsed.type !== "notes") return null;
return await MessagingMessages.findOneBy({
id: parsed.id
});
} else {
return await MessagingMessages.findOneBy({
uri: parsed.uri
});
}
}
/**
* AP Person => Misskey User in DB
*/ async getUserFromApId(value) {
const parsed = parseUri(value);
if (parsed.local) {
if (parsed.type !== "users") return null;
return await userByIdCache.fetchMaybe(parsed.id, ()=>Users.findOneBy({
id: parsed.id
}).then((x)=>x ?? undefined), true) ?? null;
} else {
return await uriPersonCache.fetch(parsed.uri, ()=>Users.findOneBy({
uri: parsed.uri
}), true);
}
}
/**
* AP KeyId => Misskey User and Key
*/ async getAuthUserFromKeyId(keyId) {
const key = await publicKeyCache.fetch(keyId, async ()=>{
const key = await UserPublickeys.findOneBy({
keyId
});
if (key == null) return null;
return key;
}, true, (key)=>key != null);
if (key == null) return null;
return {
user: await userByIdCache.fetch(key.userId, ()=>Users.findOneByOrFail({
id: key.userId
}), true),
key
};
}
/**
* AP Actor id => Misskey User and Key
*/ async getAuthUserFromApId(uri) {
const user = await resolvePerson(uri);
if (user == null) return null;
const key = await publicKeyByUserIdCache.fetch(user.id, ()=>UserPublickeys.findOneBy({
userId: user.id
}), true, (v)=>v != null);
return {
user,
key
};
}
async refetchPublicKeyForApId(user) {
try {
await updatePerson(user.uri, undefined, undefined, user);
let key = await UserPublickeys.findOneBy({
userId: user.id
});
if (key != null) {
await publicKeyByUserIdCache.set(user.id, key);
}
return key;
} catch {
return null;
}
}
}
subscriber.on("message", async (_, data)=>{
const obj = JSON.parse(data);
if (obj.channel === "internal") {
const { type, body } = obj.message;
switch(type){
case "remoteUserDeleted":
case "localUserDeleted":
{
const toDelete = Array.from(await publicKeyByUserIdCache.getAll()).filter((v)=>v[1]?.userId === body.id).map((v)=>v[0]);
const toDeleteKey = Array.from(await publicKeyCache.getAll()).filter((v)=>v[1]?.userId === body.id).map((v)=>v[0]);
await publicKeyByUserIdCache.delete(...toDelete);
await publicKeyCache.delete(...toDeleteKey);
break;
}
default:
break;
}
}
});