]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/helpers/custom-validators/activitypub/actor.ts
Move normalize functions in helpers
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / activitypub / actor.ts
1 import * as validator from 'validator'
2 import { CONSTRAINTS_FIELDS } from '../../../initializers'
3 import { exists } from '../misc'
4 import { truncate } from 'lodash'
5 import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc'
6
7 function isActorEndpointsObjectValid (endpointObject: any) {
8 return isActivityPubUrlValid(endpointObject.sharedInbox)
9 }
10
11 function isActorPublicKeyObjectValid (publicKeyObject: any) {
12 return isActivityPubUrlValid(publicKeyObject.id) &&
13 isActivityPubUrlValid(publicKeyObject.owner) &&
14 isActorPublicKeyValid(publicKeyObject.publicKeyPem)
15 }
16
17 function isActorTypeValid (type: string) {
18 return type === 'Person' || type === 'Application' || type === 'Group'
19 }
20
21 function isActorPublicKeyValid (publicKey: string) {
22 return exists(publicKey) &&
23 typeof publicKey === 'string' &&
24 publicKey.startsWith('-----BEGIN PUBLIC KEY-----') &&
25 publicKey.indexOf('-----END PUBLIC KEY-----') !== -1 &&
26 validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY)
27 }
28
29 const actorNameRegExp = new RegExp('[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_]+')
30 function isActorPreferredUsernameValid (preferredUsername: string) {
31 return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp)
32 }
33
34 function isActorPrivateKeyValid (privateKey: string) {
35 return exists(privateKey) &&
36 typeof privateKey === 'string' &&
37 privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') &&
38 // Sometimes there is a \n at the end, so just assert the string contains the end mark
39 privateKey.indexOf('-----END RSA PRIVATE KEY-----') !== -1 &&
40 validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY)
41 }
42
43 function isActorObjectValid (actor: any) {
44 return exists(actor) &&
45 isActivityPubUrlValid(actor.id) &&
46 isActorTypeValid(actor.type) &&
47 isActivityPubUrlValid(actor.following) &&
48 isActivityPubUrlValid(actor.followers) &&
49 isActivityPubUrlValid(actor.inbox) &&
50 isActivityPubUrlValid(actor.outbox) &&
51 isActorPreferredUsernameValid(actor.preferredUsername) &&
52 isActivityPubUrlValid(actor.url) &&
53 isActorPublicKeyObjectValid(actor.publicKey) &&
54 isActorEndpointsObjectValid(actor.endpoints) &&
55 setValidAttributedTo(actor) &&
56
57 // If this is not an account, it should be attributed to an account
58 // In PeerTube we use this to attach a video channel to a specific account
59 (actor.type === 'Person' || actor.attributedTo.length !== 0)
60 }
61
62 function isActorFollowingCountValid (value: string) {
63 return exists(value) && validator.isInt('' + value, { min: 0 })
64 }
65
66 function isActorFollowersCountValid (value: string) {
67 return exists(value) && validator.isInt('' + value, { min: 0 })
68 }
69
70 function isActorDeleteActivityValid (activity: any) {
71 return isBaseActivityValid(activity, 'Delete')
72 }
73
74 function isActorFollowActivityValid (activity: any) {
75 return isBaseActivityValid(activity, 'Follow') &&
76 isActivityPubUrlValid(activity.object)
77 }
78
79 function isActorAcceptActivityValid (activity: any) {
80 return isBaseActivityValid(activity, 'Accept')
81 }
82
83 function isActorRejectActivityValid (activity: any) {
84 return isBaseActivityValid(activity, 'Reject')
85 }
86
87 function isActorUpdateActivityValid (activity: any) {
88 normalizeActor(activity.object)
89
90 return isBaseActivityValid(activity, 'Update') &&
91 isActorObjectValid(activity.object)
92 }
93
94 function normalizeActor (actor: any) {
95 if (!actor) return
96
97 if (typeof actor.url !== 'string') {
98 actor.url = actor.url.href || actor.url.url
99 }
100
101 if (actor.summary && typeof actor.summary === 'string') {
102 actor.summary = truncate(actor.summary, { length: CONSTRAINTS_FIELDS.USERS.DESCRIPTION.max })
103
104 if (actor.summary.length < CONSTRAINTS_FIELDS.USERS.DESCRIPTION.min) {
105 actor.summary = null
106 }
107 }
108
109 return
110 }
111
112 // ---------------------------------------------------------------------------
113
114 export {
115 normalizeActor,
116 isActorEndpointsObjectValid,
117 isActorPublicKeyObjectValid,
118 isActorTypeValid,
119 isActorPublicKeyValid,
120 isActorPreferredUsernameValid,
121 isActorPrivateKeyValid,
122 isActorObjectValid,
123 isActorFollowingCountValid,
124 isActorFollowersCountValid,
125 isActorFollowActivityValid,
126 isActorAcceptActivityValid,
127 isActorRejectActivityValid,
128 isActorDeleteActivityValid,
129 isActorUpdateActivityValid
130 }