]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/helpers/custom-validators/activitypub/actor.ts
Begin moving video channel to actor
[github/Chocobozzz/PeerTube.git] / server / helpers / custom-validators / activitypub / actor.ts
CommitLineData
50d6de9c
C
1import * as Bluebird from 'bluebird'
2import { Response } from 'express'
fadf619a
C
3import * as validator from 'validator'
4import { CONSTRAINTS_FIELDS } from '../../../initializers'
50d6de9c 5import { ActorModel } from '../../../models/activitypub/actor'
fadf619a
C
6import { isAccountNameValid } from '../accounts'
7import { exists, isUUIDValid } from '../misc'
50d6de9c
C
8import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../video-channels'
9import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from './misc'
fadf619a
C
10
11function isActorEndpointsObjectValid (endpointObject: any) {
12 return isActivityPubUrlValid(endpointObject.sharedInbox)
13}
14
15function isActorPublicKeyObjectValid (publicKeyObject: any) {
16 return isActivityPubUrlValid(publicKeyObject.id) &&
17 isActivityPubUrlValid(publicKeyObject.owner) &&
18 isActorPublicKeyValid(publicKeyObject.publicKeyPem)
19}
20
21function isActorTypeValid (type: string) {
22 return type === 'Person' || type === 'Application' || type === 'Group'
23}
24
25function 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
33function isActorPreferredUsernameValid (preferredUsername: string) {
50d6de9c
C
34 return isAccountNameValid(preferredUsername) || isVideoChannelNameValid(preferredUsername)
35}
36
37const actorNameRegExp = new RegExp('[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_]+')
38function isActorNameValid (name: string) {
39 return exists(name) && validator.matches(name, actorNameRegExp)
fadf619a
C
40}
41
42function 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
50function 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
70function isActorFollowingCountValid (value: string) {
71 return exists(value) && validator.isInt('' + value, { min: 0 })
72}
73
74function isActorFollowersCountValid (value: string) {
75 return exists(value) && validator.isInt('' + value, { min: 0 })
76}
77
78function isActorDeleteActivityValid (activity: any) {
79 return isBaseActivityValid(activity, 'Delete')
80}
81
82function isActorFollowActivityValid (activity: any) {
83 return isBaseActivityValid(activity, 'Follow') &&
84 isActivityPubUrlValid(activity.object)
85}
86
87function isActorAcceptActivityValid (activity: any) {
88 return isBaseActivityValid(activity, 'Accept')
89}
90
50d6de9c
C
91function 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
103function isLocalActorNameExist (name: string, res: Response) {
104 const promise = ActorModel.loadLocalByName(name)
105
106 return isActorExist(promise, res)
107}
108
109async 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
127export {
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}