]>
Commit | Line | Data |
---|---|---|
50d6de9c C |
1 | import * as Bluebird from 'bluebird' |
2 | import { Response } from 'express' | |
fadf619a C |
3 | import * as validator from 'validator' |
4 | import { CONSTRAINTS_FIELDS } from '../../../initializers' | |
50d6de9c | 5 | import { ActorModel } from '../../../models/activitypub/actor' |
fadf619a C |
6 | import { isAccountNameValid } from '../accounts' |
7 | import { exists, isUUIDValid } from '../misc' | |
50d6de9c C |
8 | import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../video-channels' |
9 | import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc' | |
fadf619a C |
10 | |
11 | function isActorEndpointsObjectValid (endpointObject: any) { | |
12 | return isActivityPubUrlValid(endpointObject.sharedInbox) | |
13 | } | |
14 | ||
15 | function isActorPublicKeyObjectValid (publicKeyObject: any) { | |
16 | return isActivityPubUrlValid(publicKeyObject.id) && | |
17 | isActivityPubUrlValid(publicKeyObject.owner) && | |
18 | isActorPublicKeyValid(publicKeyObject.publicKeyPem) | |
19 | } | |
20 | ||
21 | function isActorTypeValid (type: string) { | |
22 | return type === 'Person' || type === 'Application' || type === 'Group' | |
23 | } | |
24 | ||
25 | function isActorPublicKeyValid (publicKey: string) { | |
26 | return exists(publicKey) && | |
27 | typeof publicKey === 'string' && | |
28 | publicKey.startsWith('-----BEGIN PUBLIC KEY-----') && | |
29 | publicKey.endsWith('-----END PUBLIC KEY-----') && | |
30 | validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTOR.PUBLIC_KEY) | |
31 | } | |
32 | ||
33 | function isActorPreferredUsernameValid (preferredUsername: string) { | |
50d6de9c C |
34 | return isAccountNameValid(preferredUsername) || isVideoChannelNameValid(preferredUsername) |
35 | } | |
36 | ||
37 | const actorNameRegExp = new RegExp('[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_]+') | |
38 | function isActorNameValid (name: string) { | |
39 | return exists(name) && validator.matches(name, actorNameRegExp) | |
fadf619a C |
40 | } |
41 | ||
42 | function isActorPrivateKeyValid (privateKey: string) { | |
43 | return exists(privateKey) && | |
44 | typeof privateKey === 'string' && | |
45 | privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') && | |
46 | privateKey.endsWith('-----END RSA PRIVATE KEY-----') && | |
47 | validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTOR.PRIVATE_KEY) | |
48 | } | |
49 | ||
50 | function isRemoteActorValid (remoteActor: any) { | |
51 | return isActivityPubUrlValid(remoteActor.id) && | |
52 | isUUIDValid(remoteActor.uuid) && | |
53 | isActorTypeValid(remoteActor.type) && | |
54 | isActivityPubUrlValid(remoteActor.following) && | |
55 | isActivityPubUrlValid(remoteActor.followers) && | |
56 | isActivityPubUrlValid(remoteActor.inbox) && | |
57 | isActivityPubUrlValid(remoteActor.outbox) && | |
50d6de9c | 58 | isActorNameValid(remoteActor.name) && |
fadf619a C |
59 | isActorPreferredUsernameValid(remoteActor.preferredUsername) && |
60 | isActivityPubUrlValid(remoteActor.url) && | |
61 | isActorPublicKeyObjectValid(remoteActor.publicKey) && | |
50d6de9c C |
62 | isActorEndpointsObjectValid(remoteActor.endpoints) && |
63 | (!remoteActor.summary || isVideoChannelDescriptionValid(remoteActor.summary)) && | |
64 | setValidAttributedTo(remoteActor) && | |
65 | // If this is not an account, it should be attributed to an account | |
66 | // In PeerTube we use this to attach a video channel to a specific account | |
67 | (remoteActor.type === 'Person' || remoteActor.attributedTo.length !== 0) | |
fadf619a C |
68 | } |
69 | ||
70 | function isActorFollowingCountValid (value: string) { | |
71 | return exists(value) && validator.isInt('' + value, { min: 0 }) | |
72 | } | |
73 | ||
74 | function isActorFollowersCountValid (value: string) { | |
75 | return exists(value) && validator.isInt('' + value, { min: 0 }) | |
76 | } | |
77 | ||
78 | function isActorDeleteActivityValid (activity: any) { | |
79 | return isBaseActivityValid(activity, 'Delete') | |
80 | } | |
81 | ||
82 | function isActorFollowActivityValid (activity: any) { | |
83 | return isBaseActivityValid(activity, 'Follow') && | |
84 | isActivityPubUrlValid(activity.object) | |
85 | } | |
86 | ||
87 | function isActorAcceptActivityValid (activity: any) { | |
88 | return isBaseActivityValid(activity, 'Accept') | |
89 | } | |
90 | ||
50d6de9c C |
91 | function isActorIdExist (id: number | string, res: Response) { |
92 | let promise: Bluebird<ActorModel> | |
93 | ||
94 | if (validator.isInt('' + id)) { | |
95 | promise = ActorModel.load(+id) | |
96 | } else { // UUID | |
97 | promise = ActorModel.loadByUUID('' + id) | |
98 | } | |
99 | ||
100 | return isActorExist(promise, res) | |
101 | } | |
102 | ||
103 | function isLocalActorNameExist (name: string, res: Response) { | |
104 | const promise = ActorModel.loadLocalByName(name) | |
105 | ||
106 | return isActorExist(promise, res) | |
107 | } | |
108 | ||
109 | async function isActorExist (p: Bluebird<ActorModel>, res: Response) { | |
110 | const actor = await p | |
111 | ||
112 | if (!actor) { | |
113 | res.status(404) | |
114 | .send({ error: 'Actor not found' }) | |
115 | .end() | |
116 | ||
117 | return false | |
118 | } | |
119 | ||
120 | res.locals.actor = actor | |
121 | ||
122 | return true | |
123 | } | |
124 | ||
fadf619a C |
125 | // --------------------------------------------------------------------------- |
126 | ||
127 | export { | |
128 | isActorEndpointsObjectValid, | |
129 | isActorPublicKeyObjectValid, | |
130 | isActorTypeValid, | |
131 | isActorPublicKeyValid, | |
132 | isActorPreferredUsernameValid, | |
133 | isActorPrivateKeyValid, | |
134 | isRemoteActorValid, | |
135 | isActorFollowingCountValid, | |
136 | isActorFollowersCountValid, | |
137 | isActorFollowActivityValid, | |
138 | isActorAcceptActivityValid, | |
50d6de9c C |
139 | isActorDeleteActivityValid, |
140 | isActorIdExist, | |
141 | isLocalActorNameExist, | |
142 | isActorNameValid, | |
143 | isActorExist | |
fadf619a | 144 | } |