Fix federation issues caused by Delete actor activities
This commit is contained in:
parent
b44a37de5a
commit
4743d69f95
|
@ -24,7 +24,7 @@ function createActivity(article: Article): Create {
|
|||
return createObject;
|
||||
}
|
||||
|
||||
export async function getActor(url: string, db: Database, forceUpdate: boolean = false): Promise<Actor> {
|
||||
export async function getActor(url: string, db: Database, forceUpdate: boolean = false): Promise<Actor | null> {
|
||||
if (!forceUpdate) {
|
||||
try {
|
||||
const cached = await getCachedActor(url, db);
|
||||
|
@ -34,7 +34,7 @@ export async function getActor(url: string, db: Database, forceUpdate: boolean =
|
|||
}
|
||||
}
|
||||
const remote = await fetchActor(url);
|
||||
cacheActor(remote, db);
|
||||
if (remote) cacheActor(remote, db);
|
||||
return remote;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ async function cacheActor(actor: Actor, db: Database) {
|
|||
});
|
||||
}
|
||||
|
||||
async function fetchActor(url: string): Promise<Actor> {
|
||||
async function fetchActor(url: string): Promise<Actor | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url,
|
||||
|
@ -91,7 +91,7 @@ async function fetchActor(url: string): Promise<Actor> {
|
|||
json: true
|
||||
}, (err, res) => {
|
||||
if (err) reject(err);
|
||||
else resolve(res.body as Actor);
|
||||
else resolve(res.body ? res.body as Actor : null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ async function handleFollow(activity: Activity, req: Request, res: Response) {
|
|||
}
|
||||
const db = req.app.get("db") as Database;
|
||||
const actor = await getActor(follow.actor, db, true); // always force re-fetch the actor on follow
|
||||
if (!actor) {
|
||||
// if the actor ceases existing between the time the Follow is sent and when receive it, ignore it and end the request
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
const acceptObject = <Accept>{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
|
|
|
@ -11,16 +11,28 @@ export = async (req: Request, res: Response, next: NextFunction) => {
|
|||
}
|
||||
const db = req.app.get("db") as Database;
|
||||
const actor = await getActor(req.body.actor as string, db);
|
||||
if (validate(req, actor.publicKey.publicKeyPem)) {
|
||||
if (actor && validate(req, actor.publicKey.publicKeyPem)) {
|
||||
next();
|
||||
} else {
|
||||
// if the first check fails, force re-fetch the actor and try again
|
||||
const actor = await getActor(req.body.actor as string, db, true);
|
||||
if (validate(req, actor.publicKey.publicKeyPem)) {
|
||||
next();
|
||||
} else {
|
||||
if (!actor) {
|
||||
// probably caused by Delete activity for an actor
|
||||
if (req.body.type === "Delete") {
|
||||
// if we don't have a cached copy of the key, we have had no interaction with actor
|
||||
// so the Delete can be safely ignored
|
||||
// we still send a 200 OK status, so that the originating instances knows it has successfully
|
||||
// delivered the Delete (we just can't act on it)
|
||||
res.status(200).end();
|
||||
} else {
|
||||
console.log(`Could not retrieve actor ${req.body.actor} to validate HTTP signature for`, req.body);
|
||||
res.status(401).end("Could not retrieve actor to validate HTTP signature");
|
||||
}
|
||||
} else if (!validate(req, actor.publicKey.publicKeyPem)) {
|
||||
console.log(`Could not validate HTTP signature for ${req.body.actor}`);
|
||||
res.status(401).end("Could not validate HTTP signature");
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue