Sharkey/src/common/remote/activitypub/resolver.ts

98 lines
2.1 KiB
TypeScript
Raw Normal View History

2018-03-31 13:55:00 +03:00
import RemoteUserObject from '../../../models/remote-user-object';
import { IObject } from './type';
const request = require('request-promise-native');
type IResult = {
resolver: Resolver;
object: IObject;
};
2018-04-01 15:56:11 +03:00
export default class Resolver {
private requesting: Set<string>;
constructor(iterable?: Iterable<string>) {
this.requesting = new Set(iterable);
2018-03-31 13:55:00 +03:00
}
2018-04-01 15:56:11 +03:00
private async resolveUnrequestedOne(value) {
if (typeof value !== 'string') {
return { resolver: this, object: value };
}
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
const resolver = new Resolver(this.requesting);
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
resolver.requesting.add(value);
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
const object = await request({
url: value,
headers: {
Accept: 'application/activity+json, application/ld+json'
},
json: true
});
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
if (object === null || (
Array.isArray(object['@context']) ?
!object['@context'].includes('https://www.w3.org/ns/activitystreams') :
object['@context'] !== 'https://www.w3.org/ns/activitystreams'
)) {
throw new Error();
}
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
return { resolver, object };
2018-03-31 13:55:00 +03:00
}
2018-04-01 15:56:11 +03:00
private async resolveCollection(value) {
if (Array.isArray(value)) {
return value;
}
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
const resolved = typeof value === 'string' ?
await this.resolveUnrequestedOne(value) :
value;
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
switch (resolved.type) {
case 'Collection':
return resolved.items;
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
case 'OrderedCollection':
return resolved.orderedItems;
2018-03-31 13:55:00 +03:00
2018-04-01 15:56:11 +03:00
default:
return [resolved];
}
2018-03-31 13:55:00 +03:00
}
2018-04-01 15:24:25 +03:00
public async resolve(value): Promise<Array<Promise<IResult>>> {
2018-04-01 15:56:11 +03:00
const collection = await this.resolveCollection(value);
2018-03-31 13:55:00 +03:00
return collection
.filter(element => !this.requesting.has(element))
2018-04-01 15:56:11 +03:00
.map(this.resolveUnrequestedOne.bind(this));
2018-03-31 13:55:00 +03:00
}
2018-04-01 15:24:25 +03:00
public resolveOne(value) {
2018-03-31 13:55:00 +03:00
if (this.requesting.has(value)) {
2018-04-01 15:24:25 +03:00
throw new Error();
2018-03-31 13:55:00 +03:00
}
2018-04-01 15:56:11 +03:00
return this.resolveUnrequestedOne(value);
2018-03-31 13:55:00 +03:00
}
2018-04-01 15:24:25 +03:00
public async resolveRemoteUserObjects(value) {
2018-04-01 15:56:11 +03:00
const collection = await this.resolveCollection(value);
2018-03-31 13:55:00 +03:00
return collection.filter(element => !this.requesting.has(element)).map(element => {
if (typeof element === 'string') {
const object = RemoteUserObject.findOne({ uri: element });
if (object !== null) {
return object;
}
}
2018-04-01 15:56:11 +03:00
return this.resolveUnrequestedOne(element);
2018-03-31 13:55:00 +03:00
});
}
}