FoundKey/packages/backend/src/remote/activitypub/db-resolver.ts
Johann150 1516ddfc9b
refactor: remove CacheableUser & co
The CacheableUser, CacheableLocalUser and CacheableRemoteUser are
identical types to User, ILocalUser and IRemoteUser so it seems
nonsensical to have different types for them.
2023-05-18 13:25:57 +02:00

104 lines
2.4 KiB
TypeScript

import escapeRegexp from 'escape-regexp';
import config from '@/config/index.js';
import { Note } from '@/models/entities/note.js';
import { User } from '@/models/entities/user.js';
import { MessagingMessage } from '@/models/entities/messaging-message.js';
import { Notes, MessagingMessages } from '@/models/index.js';
import { uriPersonCache, userByIdCache } from '@/services/user-cache.js';
import { IObject, getApId } from './type.js';
export type UriParseResult = {
/** wether the URI was generated by us */
local: true;
/** id in DB */
id: string;
/** hint of type, e.g. "notes", "users" */
type: string;
/** any remaining text after type and id, not including the slash after id. undefined if empty */
rest?: string;
} | {
/** wether the URI was generated by us */
local: false;
/** uri in DB */
uri: string;
};
export function parseUri(value: string | IObject): UriParseResult {
const uri = getApId(value);
// the host part of a URL is case insensitive, so use the 'i' flag.
const localRegex = new RegExp('^' + escapeRegexp(config.url) + '/(\\w+)/(\\w+)(?:\/(.+))?', 'i');
const matchLocal = uri.match(localRegex);
if (matchLocal) {
return {
local: true,
type: matchLocal[1],
id: matchLocal[2],
rest: matchLocal[3],
};
} else {
return {
local: false,
uri,
};
}
}
export class DbResolver {
constructor() {
}
/**
* AP Note => FoundKey Note in DB
*/
public async getNoteFromApId(value: string | IObject): Promise<Note | null> {
const parsed = parseUri(value);
if (parsed.local) {
if (parsed.type !== 'notes') return null;
return await Notes.findOneBy({
id: parsed.id,
});
} else {
return await Notes.findOneBy([{
uri: parsed.uri,
}, {
url: parsed.uri,
}]);
}
}
public async getMessageFromApId(value: string | IObject): Promise<MessagingMessage | null> {
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 => FoundKey User in DB
*/
public async getUserFromApId(value: string | IObject): Promise<User | null> {
const parsed = parseUri(value);
if (parsed.local) {
if (parsed.type !== 'users') return null;
return await userByIdCache.fetch(parsed.id) ?? null;
} else {
return await uriPersonCache.fetch(parsed.uri) ?? null;
}
}
}