aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-11-16 11:08:25 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-11-27 19:40:52 +0100
commitefc32059d980c51793e8e9ac0fb6a885a8026f94 (patch)
treec272e63fd57a9625b53dc26ceb1b46aee35d21d3 /server/helpers
parentd846501818c2d29e66e6fd141789cb04fd55a437 (diff)
downloadPeerTube-efc32059d980c51793e8e9ac0fb6a885a8026f94.tar.gz
PeerTube-efc32059d980c51793e8e9ac0fb6a885a8026f94.tar.zst
PeerTube-efc32059d980c51793e8e9ac0fb6a885a8026f94.zip
Send server announce when users upload a video
Diffstat (limited to 'server/helpers')
-rw-r--r--server/helpers/activitypub.ts30
-rw-r--r--server/helpers/core-utils.ts9
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts15
-rw-r--r--server/helpers/peertube-crypto.ts10
-rw-r--r--server/helpers/utils.ts18
5 files changed, 55 insertions, 27 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index de20ba55d..b376b8ca2 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -1,15 +1,19 @@
1import { join } from 'path' 1import { join } from 'path'
2import * as request from 'request' 2import * as request from 'request'
3import * as Sequelize from 'sequelize'
3import * as url from 'url' 4import * as url from 'url'
4import { ActivityIconObject } from '../../shared/index' 5import { ActivityIconObject } from '../../shared/index'
5import { ActivityPubActor } from '../../shared/models/activitypub/activitypub-actor' 6import { ActivityPubActor } from '../../shared/models/activitypub/activitypub-actor'
6import { ResultList } from '../../shared/models/result-list.model' 7import { ResultList } from '../../shared/models/result-list.model'
7import { database as db, REMOTE_SCHEME } from '../initializers' 8import { database as db, REMOTE_SCHEME } from '../initializers'
8import { ACTIVITY_PUB_ACCEPT_HEADER, CONFIG, STATIC_PATHS } from '../initializers/constants' 9import { ACTIVITY_PUB_ACCEPT_HEADER, CONFIG, STATIC_PATHS } from '../initializers/constants'
10import { sendAnnounce } from '../lib/activitypub/send-request'
11import { VideoChannelInstance } from '../models/video/video-channel-interface'
9import { VideoInstance } from '../models/video/video-interface' 12import { VideoInstance } from '../models/video/video-interface'
10import { isRemoteAccountValid } from './custom-validators' 13import { isRemoteAccountValid } from './custom-validators'
11import { logger } from './logger' 14import { logger } from './logger'
12import { doRequest, doRequestAndSaveToFile } from './requests' 15import { doRequest, doRequestAndSaveToFile } from './requests'
16import { getServerAccount } from './utils'
13 17
14function generateThumbnailFromUrl (video: VideoInstance, icon: ActivityIconObject) { 18function generateThumbnailFromUrl (video: VideoInstance, icon: ActivityIconObject) {
15 const thumbnailName = video.getThumbnailName() 19 const thumbnailName = video.getThumbnailName()
@@ -22,6 +26,28 @@ function generateThumbnailFromUrl (video: VideoInstance, icon: ActivityIconObjec
22 return doRequestAndSaveToFile(options, thumbnailPath) 26 return doRequestAndSaveToFile(options, thumbnailPath)
23} 27}
24 28
29async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) {
30 const serverAccount = await getServerAccount()
31
32 await db.VideoChannelShare.create({
33 accountId: serverAccount.id,
34 videoChannelId: videoChannel.id
35 }, { transaction: t })
36
37 return sendAnnounce(serverAccount, videoChannel, t)
38}
39
40async function shareVideoByServer (video: VideoInstance, t: Sequelize.Transaction) {
41 const serverAccount = await getServerAccount()
42
43 await db.VideoShare.create({
44 accountId: serverAccount.id,
45 videoId: video.id
46 }, { transaction: t })
47
48 return sendAnnounce(serverAccount, video, t)
49}
50
25function getActivityPubUrl (type: 'video' | 'videoChannel' | 'account' | 'videoAbuse', id: string) { 51function getActivityPubUrl (type: 'video' | 'videoChannel' | 'account' | 'videoAbuse', id: string) {
26 if (type === 'video') return CONFIG.WEBSERVER.URL + '/videos/watch/' + id 52 if (type === 'video') return CONFIG.WEBSERVER.URL + '/videos/watch/' + id
27 else if (type === 'videoChannel') return CONFIG.WEBSERVER.URL + '/video-channels/' + id 53 else if (type === 'videoChannel') return CONFIG.WEBSERVER.URL + '/video-channels/' + id
@@ -172,7 +198,9 @@ export {
172 generateThumbnailFromUrl, 198 generateThumbnailFromUrl,
173 getOrCreateAccount, 199 getOrCreateAccount,
174 fetchRemoteVideoPreview, 200 fetchRemoteVideoPreview,
175 fetchRemoteVideoDescription 201 fetchRemoteVideoDescription,
202 shareVideoChannelByServer,
203 shareVideoByServer
176} 204}
177 205
178// --------------------------------------------------------------------------- 206// ---------------------------------------------------------------------------
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index d8748e1d7..4ff07848c 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -20,9 +20,6 @@ import * as bcrypt from 'bcrypt'
20import * as createTorrent from 'create-torrent' 20import * as createTorrent from 'create-torrent'
21import * as rimraf from 'rimraf' 21import * as rimraf from 'rimraf'
22import * as pem from 'pem' 22import * as pem from 'pem'
23import * as jsonld from 'jsonld'
24import * as jsig from 'jsonld-signatures'
25jsig.use('jsonld', jsonld)
26 23
27function isTestInstance () { 24function isTestInstance () {
28 return process.env.NODE_ENV === 'test' 25 return process.env.NODE_ENV === 'test'
@@ -120,8 +117,6 @@ const bcryptHashPromise = promisify2<any, string | number, string>(bcrypt.hash)
120const createTorrentPromise = promisify2<string, any, any>(createTorrent) 117const createTorrentPromise = promisify2<string, any, any>(createTorrent)
121const rimrafPromise = promisify1WithVoid<string>(rimraf) 118const rimrafPromise = promisify1WithVoid<string>(rimraf)
122const statPromise = promisify1<string, Stats>(stat) 119const statPromise = promisify1<string, Stats>(stat)
123const jsonldSignPromise = promisify2<object, { privateKeyPem: string, creator: string }, object>(jsig.sign)
124const jsonldVerifyPromise = promisify2<object, object, object>(jsig.verify)
125 120
126// --------------------------------------------------------------------------- 121// ---------------------------------------------------------------------------
127 122
@@ -150,7 +145,5 @@ export {
150 bcryptHashPromise, 145 bcryptHashPromise,
151 createTorrentPromise, 146 createTorrentPromise,
152 rimrafPromise, 147 rimrafPromise,
153 statPromise, 148 statPromise
154 jsonldSignPromise,
155 jsonldVerifyPromise
156} 149}
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index 9ddacd601..89c49b0df 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -34,7 +34,7 @@ function isActivityPubVideoDurationValid (value: string) {
34 typeof value === 'string' && 34 typeof value === 'string' &&
35 value.startsWith('PT') && 35 value.startsWith('PT') &&
36 value.endsWith('S') && 36 value.endsWith('S') &&
37 isVideoDurationValid(value.replace(/[^0-9]+/, '')) 37 isVideoDurationValid(value.replace(/[^0-9]+/g, ''))
38} 38}
39 39
40function isVideoTorrentObjectValid (video: any) { 40function isVideoTorrentObjectValid (video: any) {
@@ -46,13 +46,14 @@ function isVideoTorrentObjectValid (video: any) {
46 isRemoteIdentifierValid(video.category) && 46 isRemoteIdentifierValid(video.category) &&
47 isRemoteIdentifierValid(video.licence) && 47 isRemoteIdentifierValid(video.licence) &&
48 isRemoteIdentifierValid(video.language) && 48 isRemoteIdentifierValid(video.language) &&
49 isVideoViewsValid(video.video) && 49 isVideoViewsValid(video.views) &&
50 isVideoNSFWValid(video.nsfw) && 50 isVideoNSFWValid(video.nsfw) &&
51 isDateValid(video.published) && 51 isDateValid(video.published) &&
52 isDateValid(video.updated) && 52 isDateValid(video.updated) &&
53 isRemoteVideoContentValid(video.mediaType, video.content) && 53 isRemoteVideoContentValid(video.mediaType, video.content) &&
54 isRemoteVideoIconValid(video.icon) && 54 isRemoteVideoIconValid(video.icon) &&
55 setValidRemoteVideoUrls(video.url) 55 setValidRemoteVideoUrls(video) &&
56 video.url.length !== 0
56} 57}
57 58
58function isVideoFlagValid (activity: any) { 59function isVideoFlagValid (activity: any) {
@@ -132,8 +133,8 @@ function isRemoteVideoIconValid (icon: any) {
132 return icon.type === 'Image' && 133 return icon.type === 'Image' &&
133 isVideoUrlValid(icon.url) && 134 isVideoUrlValid(icon.url) &&
134 icon.mediaType === 'image/jpeg' && 135 icon.mediaType === 'image/jpeg' &&
135 validator.isInt(icon.width, { min: 0 }) && 136 validator.isInt(icon.width + '', { min: 0 }) &&
136 validator.isInt(icon.height, { min: 0 }) 137 validator.isInt(icon.height + '', { min: 0 })
137} 138}
138 139
139function setValidRemoteVideoUrls (video: any) { 140function setValidRemoteVideoUrls (video: any) {
@@ -149,6 +150,6 @@ function isRemoteVideoUrlValid (url: any) {
149 return url.type === 'Link' && 150 return url.type === 'Link' &&
150 ACTIVITY_PUB.VIDEO_URL_MIME_TYPES.indexOf(url.mimeType) !== -1 && 151 ACTIVITY_PUB.VIDEO_URL_MIME_TYPES.indexOf(url.mimeType) !== -1 &&
151 isVideoUrlValid(url.url) && 152 isVideoUrlValid(url.url) &&
152 validator.isInt(url.width, { min: 0 }) && 153 validator.isInt(url.width + '', { min: 0 }) &&
153 validator.isInt(url.size, { min: 0 }) 154 validator.isInt(url.size + '', { min: 0 })
154} 155}
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts
index 6d50e446f..04a8d5681 100644
--- a/server/helpers/peertube-crypto.ts
+++ b/server/helpers/peertube-crypto.ts
@@ -1,4 +1,6 @@
1import * as jsonld from 'jsonld'
1import * as jsig from 'jsonld-signatures' 2import * as jsig from 'jsonld-signatures'
3jsig.use('jsonld', jsonld)
2 4
3import { 5import {
4 PRIVATE_RSA_KEY_SIZE, 6 PRIVATE_RSA_KEY_SIZE,
@@ -9,9 +11,7 @@ import {
9 bcryptGenSaltPromise, 11 bcryptGenSaltPromise,
10 bcryptHashPromise, 12 bcryptHashPromise,
11 createPrivateKey, 13 createPrivateKey,
12 getPublicKey, 14 getPublicKey
13 jsonldSignPromise,
14 jsonldVerifyPromise
15} from './core-utils' 15} from './core-utils'
16import { logger } from './logger' 16import { logger } from './logger'
17import { AccountInstance } from '../models/account/account-interface' 17import { AccountInstance } from '../models/account/account-interface'
@@ -45,7 +45,7 @@ function isSignatureVerified (fromAccount: AccountInstance, signedDocument: obje
45 publicKeyOwner: publicKeyOwnerObject 45 publicKeyOwner: publicKeyOwnerObject
46 } 46 }
47 47
48 return jsonldVerifyPromise(signedDocument, options) 48 return jsig.promises.verify(signedDocument, options)
49 .catch(err => { 49 .catch(err => {
50 logger.error('Cannot check signature.', err) 50 logger.error('Cannot check signature.', err)
51 return false 51 return false
@@ -58,7 +58,7 @@ function signObject (byAccount: AccountInstance, data: any) {
58 creator: byAccount.url 58 creator: byAccount.url
59 } 59 }
60 60
61 return jsonldSignPromise(data, options) 61 return jsig.promises.sign(data, options)
62} 62}
63 63
64function comparePassword (plainPassword: string, hashPassword: string) { 64function comparePassword (plainPassword: string, hashPassword: string) {
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts
index 39957c90f..3af14a68a 100644
--- a/server/helpers/utils.ts
+++ b/server/helpers/utils.ts
@@ -6,6 +6,7 @@ import { CONFIG, database as db } from '../initializers'
6import { ResultList } from '../../shared' 6import { ResultList } from '../../shared'
7import { VideoResolution } from '../../shared/models/videos/video-resolution.enum' 7import { VideoResolution } from '../../shared/models/videos/video-resolution.enum'
8import { AccountInstance } from '../models/account/account-interface' 8import { AccountInstance } from '../models/account/account-interface'
9import { logger } from './logger'
9 10
10function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) { 11function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) {
11 return res.type('json').status(400).end() 12 return res.type('json').status(400).end()
@@ -79,13 +80,18 @@ function resetSequelizeInstance (instance: Sequelize.Instance<any>, savedFields:
79 }) 80 })
80} 81}
81 82
82let applicationAccount: AccountInstance 83let serverAccount: AccountInstance
83async function getApplicationAccount () { 84async function getServerAccount () {
84 if (applicationAccount === undefined) { 85 if (serverAccount === undefined) {
85 applicationAccount = await db.Account.loadApplication() 86 serverAccount = await db.Account.loadApplication()
86 } 87 }
87 88
88 return Promise.resolve(applicationAccount) 89 if (!serverAccount) {
90 logger.error('Cannot load server account.')
91 process.exit(0)
92 }
93
94 return Promise.resolve(serverAccount)
89} 95}
90 96
91type SortType = { sortModel: any, sortValue: string } 97type SortType = { sortModel: any, sortValue: string }
@@ -99,6 +105,6 @@ export {
99 isSignupAllowed, 105 isSignupAllowed,
100 computeResolutionsToTranscode, 106 computeResolutionsToTranscode,
101 resetSequelizeInstance, 107 resetSequelizeInstance,
102 getApplicationAccount, 108 getServerAccount,
103 SortType 109 SortType
104} 110}