summaryrefslogtreecommitdiff
path: root/src/remote/activitypub/db-resolver.ts
blob: 9fc6f0c3b7b2af7ad290f37cd17c2b74989a4a65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import config from '@/config';
import { Note } from '../../models/entities/note';
import { User, IRemoteUser } from '../../models/entities/user';
import { UserPublickey } from '../../models/entities/user-publickey';
import { MessagingMessage } from '../../models/entities/messaging-message';
import { Notes, Users, UserPublickeys, MessagingMessages } from '../../models';
import { IObject, getApId } from './type';
import { resolvePerson } from './models/person';
import escapeRegexp = require('escape-regexp');

export default class DbResolver {
	constructor() {
	}

	/**
	 * AP Note => Misskey Note in DB
	 */
	public async getNoteFromApId(value: string | IObject): Promise<Note | null> {
		const parsed = this.parseUri(value);

		if (parsed.id) {
			return (await Notes.findOne({
				id: parsed.id
			})) || null;
		}

		if (parsed.uri) {
			return (await Notes.findOne({
				uri: parsed.uri
			})) || null;
		}

		return null;
	}

	public async getMessageFromApId(value: string | IObject): Promise<MessagingMessage | null> {
		const parsed = this.parseUri(value);

		if (parsed.id) {
			return (await MessagingMessages.findOne({
				id: parsed.id
			})) || null;
		}

		if (parsed.uri) {
			return (await MessagingMessages.findOne({
				uri: parsed.uri
			})) || null;
		}

		return null;
	}

	/**
	 * AP Person => Misskey User in DB
	 */
	public async getUserFromApId(value: string | IObject): Promise<User | null> {
		const parsed = this.parseUri(value);

		if (parsed.id) {
			return (await Users.findOne({
				id: parsed.id
			})) || null;
		}

		if (parsed.uri) {
			return (await Users.findOne({
				uri: parsed.uri
			})) || null;
		}

		return null;
	}

	/**
	 * AP KeyId => Misskey User and Key
	 */
	public async getAuthUserFromKeyId(keyId: string): Promise<AuthUser | null> {
		const key = await UserPublickeys.findOne({
			keyId
		});

		if (key == null) return null;

		const user = await Users.findOne(key.userId) as IRemoteUser;

		return {
			user,
			key
		};
	}

	/**
	 * AP Actor id => Misskey User and Key
	 */
	public async getAuthUserFromApId(uri: string): Promise<AuthUser | null> {
		const user = await resolvePerson(uri) as IRemoteUser;

		if (user == null) return null;

		const key = await UserPublickeys.findOne(user.id);

		return {
			user,
			key
		};
	}

	public parseUri(value: string | IObject): UriParseResult {
		const uri = getApId(value);

		const localRegex = new RegExp('^' + escapeRegexp(config.url) + '/' + '(\\w+)' + '/' + '(\\w+)');
		const matchLocal = uri.match(localRegex);

		if (matchLocal) {
			return {
				type: matchLocal[1],
				id: matchLocal[2]
			};
		} else {
			return {
				uri
			};
		}
	}
}

export type AuthUser = {
	user: IRemoteUser;
	key?: UserPublickey;
};

type UriParseResult = {
	/** id in DB (local object only) */
	id?: string;
	/** uri in DB (remote object only) */
	uri?: string;
	/** hint of type (local object only, ex: notes, users) */
	type?: string
};