aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-11-14 20:03:04 +0100
committerChocobozzz <florian.bigard@gmail.com>2016-11-16 20:29:26 +0100
commit49abbbbedca83b9031d3e2eb3ae9ad9b6a7d96ed (patch)
tree68c59d67637a297d513e07ea96ba236a7f0cd43b
parent41b5da1d8cb41f5c49f0e0a01a54106c9a5925dd (diff)
downloadPeerTube-49abbbbedca83b9031d3e2eb3ae9ad9b6a7d96ed.tar.gz
PeerTube-49abbbbedca83b9031d3e2eb3ae9ad9b6a7d96ed.tar.zst
PeerTube-49abbbbedca83b9031d3e2eb3ae9ad9b6a7d96ed.zip
Pod URL -> pod host. HTTPS is required to make friends.
Reason: in a network with mix http/https pods, https pods won't be able to play videos from http pod (insecure requests).
-rw-r--r--client/src/app/admin/friends/friend-add/friend-add.component.html12
-rw-r--r--client/src/app/admin/friends/friend-add/friend-add.component.ts56
-rw-r--r--client/src/app/admin/friends/friend-list/friend-list.component.html4
-rw-r--r--client/src/app/admin/friends/shared/friend.model.ts2
-rw-r--r--client/src/app/admin/friends/shared/friend.service.ts4
-rw-r--r--client/src/app/shared/forms/form-validators/host.validator.ts11
-rw-r--r--client/src/app/shared/forms/form-validators/index.ts2
-rw-r--r--client/src/app/shared/forms/form-validators/url.validator.ts11
-rw-r--r--client/src/app/videos/shared/video.model.ts21
-rw-r--r--client/src/app/videos/video-watch/video-watch.component.html2
-rw-r--r--server/controllers/api/pods.js16
-rw-r--r--server/controllers/api/remote.js12
-rw-r--r--server/helpers/custom-validators/pods.js12
-rw-r--r--server/helpers/custom-validators/videos.js6
-rw-r--r--server/helpers/requests.js8
-rw-r--r--server/initializers/constants.js3
-rw-r--r--server/lib/friends.js59
-rw-r--r--server/middlewares/pods.js50
-rw-r--r--server/middlewares/secure.js14
-rw-r--r--server/middlewares/validators/pods.js4
-rw-r--r--server/middlewares/validators/remote.js4
-rw-r--r--server/models/pods.js17
-rw-r--r--server/models/request.js2
-rw-r--r--server/models/video.js32
24 files changed, 168 insertions, 196 deletions
diff --git a/client/src/app/admin/friends/friend-add/friend-add.component.html b/client/src/app/admin/friends/friend-add/friend-add.component.html
index 788f3b44d..621822860 100644
--- a/client/src/app/admin/friends/friend-add/friend-add.component.html
+++ b/client/src/app/admin/friends/friend-add/friend-add.component.html
@@ -3,13 +3,13 @@
3<div *ngIf="error" class="alert alert-danger">{{ error }}</div> 3<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
4 4
5<form (ngSubmit)="makeFriends()" [formGroup]="form"> 5<form (ngSubmit)="makeFriends()" [formGroup]="form">
6 <div class="form-group" *ngFor="let url of urls; let id = index; trackBy:customTrackBy"> 6 <div class="form-group" *ngFor="let host of hosts; let id = index; trackBy:customTrackBy">
7 <label for="username">Url</label> 7 <label for="username">Host</label>
8 8
9 <div class="input-group"> 9 <div class="input-group">
10 <input 10 <input
11 type="text" class="form-control" placeholder="http://domain.com" 11 type="text" class="form-control" placeholder="domain.tld"
12 [id]="'url-' + id" [formControlName]="'url-' + id" 12 [id]="'host-' + id" [formControlName]="'host-' + id"
13 /> 13 />
14 <span class="input-group-btn"> 14 <span class="input-group-btn">
15 <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button> 15 <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
@@ -17,8 +17,8 @@
17 </span> 17 </span>
18 </div> 18 </div>
19 19
20 <div [hidden]="form.controls['url-' + id].valid || form.controls['url-' + id].pristine" class="alert alert-warning"> 20 <div [hidden]="form.controls['host-' + id].valid || form.controls['host-' + id].pristine" class="alert alert-warning">
21 It should be a valid url. 21 It should be a valid host.
22 </div> 22 </div>
23 </div> 23 </div>
24 24
diff --git a/client/src/app/admin/friends/friend-add/friend-add.component.ts b/client/src/app/admin/friends/friend-add/friend-add.component.ts
index 64165a9a5..86b018de2 100644
--- a/client/src/app/admin/friends/friend-add/friend-add.component.ts
+++ b/client/src/app/admin/friends/friend-add/friend-add.component.ts
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
2import { FormControl, FormGroup } from '@angular/forms'; 2import { FormControl, FormGroup } from '@angular/forms';
3import { Router } from '@angular/router'; 3import { Router } from '@angular/router';
4 4
5import { validateUrl } from '../../../shared'; 5import { validateHost } from '../../../shared';
6import { FriendService } from '../shared'; 6import { FriendService } from '../shared';
7 7
8@Component({ 8@Component({
@@ -12,7 +12,7 @@ import { FriendService } from '../shared';
12}) 12})
13export class FriendAddComponent implements OnInit { 13export class FriendAddComponent implements OnInit {
14 form: FormGroup; 14 form: FormGroup;
15 urls = [ ]; 15 hosts = [ ];
16 error: string = null; 16 error: string = null;
17 17
18 constructor(private router: Router, private friendService: FriendService) {} 18 constructor(private router: Router, private friendService: FriendService) {}
@@ -23,8 +23,8 @@ export class FriendAddComponent implements OnInit {
23 } 23 }
24 24
25 addField() { 25 addField() {
26 this.form.addControl(`url-${this.urls.length}`, new FormControl('', [ validateUrl ])); 26 this.form.addControl(`host-${this.hosts.length}`, new FormControl('', [ validateHost ]));
27 this.urls.push(''); 27 this.hosts.push('');
28 } 28 }
29 29
30 customTrackBy(index: number, obj: any): any { 30 customTrackBy(index: number, obj: any): any {
@@ -32,52 +32,52 @@ export class FriendAddComponent implements OnInit {
32 } 32 }
33 33
34 displayAddField(index: number) { 34 displayAddField(index: number) {
35 return index === (this.urls.length - 1); 35 return index === (this.hosts.length - 1);
36 } 36 }
37 37
38 displayRemoveField(index: number) { 38 displayRemoveField(index: number) {
39 return (index !== 0 || this.urls.length > 1) && index !== (this.urls.length - 1); 39 return (index !== 0 || this.hosts.length > 1) && index !== (this.hosts.length - 1);
40 } 40 }
41 41
42 isFormValid() { 42 isFormValid() {
43 // Do not check the last input 43 // Do not check the last input
44 for (let i = 0; i < this.urls.length - 1; i++) { 44 for (let i = 0; i < this.hosts.length - 1; i++) {
45 if (!this.form.controls[`url-${i}`].valid) return false; 45 if (!this.form.controls[`host-${i}`].valid) return false;
46 } 46 }
47 47
48 const lastIndex = this.urls.length - 1; 48 const lastIndex = this.hosts.length - 1;
49 // If the last input (which is not the first) is empty, it's ok 49 // If the last input (which is not the first) is empty, it's ok
50 if (this.urls[lastIndex] === '' && lastIndex !== 0) { 50 if (this.hosts[lastIndex] === '' && lastIndex !== 0) {
51 return true; 51 return true;
52 } else { 52 } else {
53 return this.form.controls[`url-${lastIndex}`].valid; 53 return this.form.controls[`host-${lastIndex}`].valid;
54 } 54 }
55 } 55 }
56 56
57 removeField(index: number) { 57 removeField(index: number) {
58 // Remove the last control 58 // Remove the last control
59 this.form.removeControl(`url-${this.urls.length - 1}`); 59 this.form.removeControl(`host-${this.hosts.length - 1}`);
60 this.urls.splice(index, 1); 60 this.hosts.splice(index, 1);
61 } 61 }
62 62
63 makeFriends() { 63 makeFriends() {
64 this.error = ''; 64 this.error = '';
65 65
66 const notEmptyUrls = this.getNotEmptyUrls(); 66 const notEmptyHosts = this.getNotEmptyHosts();
67 if (notEmptyUrls.length === 0) { 67 if (notEmptyHosts.length === 0) {
68 this.error = 'You need to specify at less 1 url.'; 68 this.error = 'You need to specify at least 1 host.';
69 return; 69 return;
70 } 70 }
71 71
72 if (!this.isUrlsUnique(notEmptyUrls)) { 72 if (!this.isHostsUnique(notEmptyHosts)) {
73 this.error = 'Urls need to be unique.'; 73 this.error = 'Hosts need to be unique.';
74 return; 74 return;
75 } 75 }
76 76
77 const confirmMessage = 'Are you sure to make friends with:\n - ' + notEmptyUrls.join('\n - '); 77 const confirmMessage = 'Are you sure to make friends with:\n - ' + notEmptyHosts.join('\n - ');
78 if (!confirm(confirmMessage)) return; 78 if (!confirm(confirmMessage)) return;
79 79
80 this.friendService.makeFriends(notEmptyUrls).subscribe( 80 this.friendService.makeFriends(notEmptyHosts).subscribe(
81 status => { 81 status => {
82 // TODO: extractdatastatus 82 // TODO: extractdatastatus
83 // if (status === 409) { 83 // if (status === 409) {
@@ -91,18 +91,18 @@ export class FriendAddComponent implements OnInit {
91 ); 91 );
92 } 92 }
93 93
94 private getNotEmptyUrls() { 94 private getNotEmptyHosts() {
95 const notEmptyUrls = []; 95 const notEmptyHosts = [];
96 96
97 Object.keys(this.form.value).forEach((urlKey) => { 97 Object.keys(this.form.value).forEach((hostKey) => {
98 const url = this.form.value[urlKey]; 98 const host = this.form.value[hostKey];
99 if (url !== '') notEmptyUrls.push(url); 99 if (host !== '') notEmptyHosts.push(host);
100 }); 100 });
101 101
102 return notEmptyUrls; 102 return notEmptyHosts;
103 } 103 }
104 104
105 private isUrlsUnique(urls: string[]) { 105 private isHostsUnique(hosts: string[]) {
106 return urls.every(url => urls.indexOf(url) === urls.lastIndexOf(url)); 106 return hosts.every(host => hosts.indexOf(host) === hosts.lastIndexOf(host));
107 } 107 }
108} 108}
diff --git a/client/src/app/admin/friends/friend-list/friend-list.component.html b/client/src/app/admin/friends/friend-list/friend-list.component.html
index 20b4d12db..4236fc5f6 100644
--- a/client/src/app/admin/friends/friend-list/friend-list.component.html
+++ b/client/src/app/admin/friends/friend-list/friend-list.component.html
@@ -4,7 +4,7 @@
4 <thead> 4 <thead>
5 <tr> 5 <tr>
6 <th class="table-column-id">ID</th> 6 <th class="table-column-id">ID</th>
7 <th>Url</th> 7 <th>Host</th>
8 <th>Score</th> 8 <th>Score</th>
9 <th>Created Date</th> 9 <th>Created Date</th>
10 </tr> 10 </tr>
@@ -13,7 +13,7 @@
13 <tbody> 13 <tbody>
14 <tr *ngFor="let friend of friends"> 14 <tr *ngFor="let friend of friends">
15 <td>{{ friend.id }}</td> 15 <td>{{ friend.id }}</td>
16 <td>{{ friend.url }}</td> 16 <td>{{ friend.host }}</td>
17 <td>{{ friend.score }}</td> 17 <td>{{ friend.score }}</td>
18 <td>{{ friend.createdDate | date: 'medium' }}</td> 18 <td>{{ friend.createdDate | date: 'medium' }}</td>
19 </tr> 19 </tr>
diff --git a/client/src/app/admin/friends/shared/friend.model.ts b/client/src/app/admin/friends/shared/friend.model.ts
index 7cb28f440..3c23feebc 100644
--- a/client/src/app/admin/friends/shared/friend.model.ts
+++ b/client/src/app/admin/friends/shared/friend.model.ts
@@ -1,6 +1,6 @@
1export interface Friend { 1export interface Friend {
2 id: string; 2 id: string;
3 url: string; 3 host: string;
4 score: number; 4 score: number;
5 createdDate: Date; 5 createdDate: Date;
6} 6}
diff --git a/client/src/app/admin/friends/shared/friend.service.ts b/client/src/app/admin/friends/shared/friend.service.ts
index 75826fc17..8a1ba6b02 100644
--- a/client/src/app/admin/friends/shared/friend.service.ts
+++ b/client/src/app/admin/friends/shared/friend.service.ts
@@ -21,9 +21,9 @@ export class FriendService {
21 .catch((res) => this.restExtractor.handleError(res)); 21 .catch((res) => this.restExtractor.handleError(res));
22 } 22 }
23 23
24 makeFriends(notEmptyUrls) { 24 makeFriends(notEmptyHosts) {
25 const body = { 25 const body = {
26 urls: notEmptyUrls 26 hosts: notEmptyHosts
27 }; 27 };
28 28
29 return this.authHttp.post(FriendService.BASE_FRIEND_URL + 'makefriends', body) 29 return this.authHttp.post(FriendService.BASE_FRIEND_URL + 'makefriends', body)
diff --git a/client/src/app/shared/forms/form-validators/host.validator.ts b/client/src/app/shared/forms/form-validators/host.validator.ts
new file mode 100644
index 000000000..9cb46d361
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/host.validator.ts
@@ -0,0 +1,11 @@
1import { FormControl } from '@angular/forms';
2
3export function validateHost(c: FormControl) {
4 let HOST_REGEXP = new RegExp('^(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$');
5
6 return HOST_REGEXP.test(c.value) ? null : {
7 validateHost: {
8 valid: false
9 }
10 };
11}
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index 1d2ae6f68..4c6cc6637 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -1,3 +1,3 @@
1export * from './url.validator'; 1export * from './host.validator';
2export * from './user'; 2export * from './user';
3export * from './video'; 3export * from './video';
diff --git a/client/src/app/shared/forms/form-validators/url.validator.ts b/client/src/app/shared/forms/form-validators/url.validator.ts
deleted file mode 100644
index 67163b4e9..000000000
--- a/client/src/app/shared/forms/form-validators/url.validator.ts
+++ /dev/null
@@ -1,11 +0,0 @@
1import { FormControl } from '@angular/forms';
2
3export function validateUrl(c: FormControl) {
4 let URL_REGEXP = new RegExp('^https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$');
5
6 return URL_REGEXP.test(c.value) ? null : {
7 validateUrl: {
8 valid: false
9 }
10 };
11}
diff --git a/client/src/app/videos/shared/video.model.ts b/client/src/app/videos/shared/video.model.ts
index 873c83ff1..b51a0e9de 100644
--- a/client/src/app/videos/shared/video.model.ts
+++ b/client/src/app/videos/shared/video.model.ts
@@ -8,21 +8,12 @@ export class Video {
8 isLocal: boolean; 8 isLocal: boolean;
9 magnetUri: string; 9 magnetUri: string;
10 name: string; 10 name: string;
11 podUrl: string; 11 podHost: string;
12 tags: string[]; 12 tags: string[];
13 thumbnailPath: string; 13 thumbnailPath: string;
14 14
15 private static createByString(author: string, podUrl: string) { 15 private static createByString(author: string, podHost: string) {
16 let [ host, port ] = podUrl.replace(/^https?:\/\//, '').split(':'); 16 return author + '@' + podHost;
17
18 if (port === '80' || port === '443') {
19 port = '';
20 } else {
21 port = ':' + port;
22 }
23
24
25 return author + '@' + host + port;
26 } 17 }
27 18
28 private static createDurationString(duration: number) { 19 private static createDurationString(duration: number) {
@@ -43,7 +34,7 @@ export class Video {
43 isLocal: boolean, 34 isLocal: boolean,
44 magnetUri: string, 35 magnetUri: string,
45 name: string, 36 name: string,
46 podUrl: string, 37 podHost: string,
47 tags: string[], 38 tags: string[],
48 thumbnailPath: string 39 thumbnailPath: string
49 }) { 40 }) {
@@ -55,11 +46,11 @@ export class Video {
55 this.isLocal = hash.isLocal; 46 this.isLocal = hash.isLocal;
56 this.magnetUri = hash.magnetUri; 47 this.magnetUri = hash.magnetUri;
57 this.name = hash.name; 48 this.name = hash.name;
58 this.podUrl = hash.podUrl; 49 this.podHost = hash.podHost;
59 this.tags = hash.tags; 50 this.tags = hash.tags;
60 this.thumbnailPath = hash.thumbnailPath; 51 this.thumbnailPath = hash.thumbnailPath;
61 52
62 this.by = Video.createByString(hash.author, hash.podUrl); 53 this.by = Video.createByString(hash.author, hash.podHost);
63 } 54 }
64 55
65 isRemovableBy(user) { 56 isRemovableBy(user) {
diff --git a/client/src/app/videos/video-watch/video-watch.component.html b/client/src/app/videos/video-watch/video-watch.component.html
index f3a416367..cb91bae7e 100644
--- a/client/src/app/videos/video-watch/video-watch.component.html
+++ b/client/src/app/videos/video-watch/video-watch.component.html
@@ -2,7 +2,7 @@
2 <div class="alert alert-danger"> 2 <div class="alert alert-danger">
3 The video load seems to be abnormally long. 3 The video load seems to be abnormally long.
4 <ul> 4 <ul>
5 <li>Maybe the server {{ video.podUrl }} is down :(</li> 5 <li>Maybe the server {{ video.podHost }} is down :(</li>
6 <li> 6 <li>
7 If not, you can report an issue on 7 If not, you can report an issue on
8 <a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue"> 8 <a href="https://github.com/Chocobozzz/PeerTube/issues" title="Report an issue">
diff --git a/server/controllers/api/pods.js b/server/controllers/api/pods.js
index 853e0705b..7857fcee0 100644
--- a/server/controllers/api/pods.js
+++ b/server/controllers/api/pods.js
@@ -20,14 +20,14 @@ const Pod = mongoose.model('Pod')
20router.get('/', listPods) 20router.get('/', listPods)
21router.post('/', 21router.post('/',
22 validators.podsAdd, 22 validators.podsAdd,
23 podsMiddleware.setBodyUrlPort, 23 podsMiddleware.setBodyHostPort,
24 addPods 24 addPods
25) 25)
26router.post('/makefriends', 26router.post('/makefriends',
27 oAuth.authenticate, 27 oAuth.authenticate,
28 admin.ensureIsAdmin, 28 admin.ensureIsAdmin,
29 validators.makeFriends, 29 validators.makeFriends,
30 podsMiddleware.setBodyUrlsPort, 30 podsMiddleware.setBodyHostsPort,
31 makeFriends 31 makeFriends
32) 32)
33router.get('/quitfriends', 33router.get('/quitfriends',
@@ -84,17 +84,17 @@ function addPods (req, res, next) {
84} 84}
85 85
86function listPods (req, res, next) { 86function listPods (req, res, next) {
87 Pod.list(function (err, podsUrlList) { 87 Pod.list(function (err, podsList) {
88 if (err) return next(err) 88 if (err) return next(err)
89 89
90 res.json(getFormatedPods(podsUrlList)) 90 res.json(getFormatedPods(podsList))
91 }) 91 })
92} 92}
93 93
94function makeFriends (req, res, next) { 94function makeFriends (req, res, next) {
95 const urls = req.body.urls 95 const hosts = req.body.hosts
96 96
97 friends.makeFriends(urls, function (err) { 97 friends.makeFriends(hosts, function (err) {
98 if (err) { 98 if (err) {
99 logger.error('Could not make friends.', { error: err }) 99 logger.error('Could not make friends.', { error: err })
100 return 100 return
@@ -107,11 +107,11 @@ function makeFriends (req, res, next) {
107} 107}
108 108
109function removePods (req, res, next) { 109function removePods (req, res, next) {
110 const url = req.body.signature.url 110 const host = req.body.signature.host
111 111
112 waterfall([ 112 waterfall([
113 function loadPod (callback) { 113 function loadPod (callback) {
114 Pod.loadByUrl(url, callback) 114 Pod.loadByHost(host, callback)
115 }, 115 },
116 116
117 function removePod (pod, callback) { 117 function removePod (pod, callback) {
diff --git a/server/controllers/api/remote.js b/server/controllers/api/remote.js
index 94808693d..4085deb2d 100644
--- a/server/controllers/api/remote.js
+++ b/server/controllers/api/remote.js
@@ -30,7 +30,7 @@ module.exports = router
30 30
31function remoteVideos (req, res, next) { 31function remoteVideos (req, res, next) {
32 const requests = req.body.data 32 const requests = req.body.data
33 const fromUrl = req.body.signature.url 33 const fromHost = req.body.signature.host
34 34
35 // We need to process in the same order to keep consistency 35 // We need to process in the same order to keep consistency
36 // TODO: optimization 36 // TODO: optimization
@@ -40,7 +40,7 @@ function remoteVideos (req, res, next) {
40 if (request.type === 'add') { 40 if (request.type === 'add') {
41 addRemoteVideo(videoData, callbackEach) 41 addRemoteVideo(videoData, callbackEach)
42 } else if (request.type === 'remove') { 42 } else if (request.type === 'remove') {
43 removeRemoteVideo(videoData, fromUrl, callbackEach) 43 removeRemoteVideo(videoData, fromHost, callbackEach)
44 } else { 44 } else {
45 logger.error('Unkown remote request type %s.', request.type) 45 logger.error('Unkown remote request type %s.', request.type)
46 } 46 }
@@ -62,16 +62,16 @@ function addRemoteVideo (videoToCreateData, callback) {
62 video.save(callback) 62 video.save(callback)
63} 63}
64 64
65function removeRemoteVideo (videoToRemoveData, fromUrl, callback) { 65function removeRemoteVideo (videoToRemoveData, fromHost, callback) {
66 // We need the list because we have to remove some other stuffs (thumbnail etc) 66 // We need the list because we have to remove some other stuffs (thumbnail etc)
67 Video.listByUrlAndRemoteId(fromUrl, videoToRemoveData.remoteId, function (err, videosList) { 67 Video.listByHostAndRemoteId(fromHost, videoToRemoveData.remoteId, function (err, videosList) {
68 if (err) { 68 if (err) {
69 logger.error('Cannot list videos from url and magnets.', { error: err }) 69 logger.error('Cannot list videos from host and magnets.', { error: err })
70 return callback(err) 70 return callback(err)
71 } 71 }
72 72
73 if (videosList.length === 0) { 73 if (videosList.length === 0) {
74 logger.error('No remote video was found for this pod.', { magnetUri: videoToRemoveData.magnetUri, podUrl: fromUrl }) 74 logger.error('No remote video was found for this pod.', { magnetUri: videoToRemoveData.magnetUri, podHost: fromHost })
75 } 75 }
76 76
77 each(videosList, function (video, callbackEach) { 77 each(videosList, function (video, callbackEach) {
diff --git a/server/helpers/custom-validators/pods.js b/server/helpers/custom-validators/pods.js
index 40f8b5d0b..0154a2424 100644
--- a/server/helpers/custom-validators/pods.js
+++ b/server/helpers/custom-validators/pods.js
@@ -5,14 +5,14 @@ const validator = require('express-validator').validator
5const miscValidators = require('./misc') 5const miscValidators = require('./misc')
6 6
7const podsValidators = { 7const podsValidators = {
8 isEachUniqueUrlValid 8 isEachUniqueHostValid
9} 9}
10 10
11function isEachUniqueUrlValid (urls) { 11function isEachUniqueHostValid (hosts) {
12 return miscValidators.isArray(urls) && 12 return miscValidators.isArray(hosts) &&
13 urls.length !== 0 && 13 hosts.length !== 0 &&
14 urls.every(function (url) { 14 hosts.every(function (host) {
15 return validator.isURL(url) && urls.indexOf(url) === urls.lastIndexOf(url) 15 return validator.isURL(host) && host.split('://').length === 1 && hosts.indexOf(host) === hosts.lastIndexOf(host)
16 }) 16 })
17} 17}
18 18
diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js
index 45acb7686..4a6a62326 100644
--- a/server/helpers/custom-validators/videos.js
+++ b/server/helpers/custom-validators/videos.js
@@ -15,7 +15,7 @@ const videosValidators = {
15 isVideoDurationValid, 15 isVideoDurationValid,
16 isVideoMagnetValid, 16 isVideoMagnetValid,
17 isVideoNameValid, 17 isVideoNameValid,
18 isVideoPodUrlValid, 18 isVideoPodHostValid,
19 isVideoTagsValid, 19 isVideoTagsValid,
20 isVideoThumbnailValid, 20 isVideoThumbnailValid,
21 isVideoThumbnail64Valid 21 isVideoThumbnail64Valid
@@ -33,7 +33,7 @@ function isEachRemoteVideosValid (requests) {
33 isVideoDurationValid(video.duration) && 33 isVideoDurationValid(video.duration) &&
34 isVideoMagnetValid(video.magnet) && 34 isVideoMagnetValid(video.magnet) &&
35 isVideoNameValid(video.name) && 35 isVideoNameValid(video.name) &&
36 isVideoPodUrlValid(video.podUrl) && 36 isVideoPodHostValid(video.podHost) &&
37 isVideoTagsValid(video.tags) && 37 isVideoTagsValid(video.tags) &&
38 isVideoThumbnail64Valid(video.thumbnailBase64) && 38 isVideoThumbnail64Valid(video.thumbnailBase64) &&
39 isVideoRemoteIdValid(video.remoteId) 39 isVideoRemoteIdValid(video.remoteId)
@@ -70,7 +70,7 @@ function isVideoNameValid (value) {
70 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME) 70 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
71} 71}
72 72
73function isVideoPodUrlValid (value) { 73function isVideoPodHostValid (value) {
74 // TODO: set options (TLD...) 74 // TODO: set options (TLD...)
75 return validator.isURL(value) 75 return validator.isURL(value)
76} 76}
diff --git a/server/helpers/requests.js b/server/helpers/requests.js
index 95775c981..06109ce16 100644
--- a/server/helpers/requests.js
+++ b/server/helpers/requests.js
@@ -25,7 +25,7 @@ function makeRetryRequest (params, callback) {
25 25
26function makeSecureRequest (params, callback) { 26function makeSecureRequest (params, callback) {
27 const requestParams = { 27 const requestParams = {
28 url: params.toPod.url + params.path 28 url: constants.REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path
29 } 29 }
30 30
31 // Add data with POST requst ? 31 // Add data with POST requst ?
@@ -34,9 +34,11 @@ function makeSecureRequest (params, callback) {
34 34
35 // Add signature if it is specified in the params 35 // Add signature if it is specified in the params
36 if (params.sign === true) { 36 if (params.sign === true) {
37 const host = constants.CONFIG.WEBSERVER.HOST
38
37 requestParams.json.signature = { 39 requestParams.json.signature = {
38 url: constants.CONFIG.WEBSERVER.URL, 40 host,
39 signature: peertubeCrypto.sign(constants.CONFIG.WEBSERVER.URL) 41 signature: peertubeCrypto.sign(host)
40 } 42 }
41 } 43 }
42 44
diff --git a/server/initializers/constants.js b/server/initializers/constants.js
index c808aff5f..d8a13d066 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.js
@@ -14,7 +14,7 @@ const PAGINATION_COUNT_DEFAULT = 15
14 14
15// Sortable columns per schema 15// Sortable columns per schema
16const SEARCHABLE_COLUMNS = { 16const SEARCHABLE_COLUMNS = {
17 VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ] 17 VIDEOS: [ 'name', 'magnetUri', 'podHost', 'author', 'tags' ]
18} 18}
19 19
20// Sortable columns per schema 20// Sortable columns per schema
@@ -55,6 +55,7 @@ const CONFIG = {
55 } 55 }
56} 56}
57CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT 57CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
58CONFIG.WEBSERVER.HOST = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
58 59
59// --------------------------------------------------------------------------- 60// ---------------------------------------------------------------------------
60 61
diff --git a/server/lib/friends.js b/server/lib/friends.js
index eafffaab0..eaea040ca 100644
--- a/server/lib/friends.js
+++ b/server/lib/friends.js
@@ -6,7 +6,6 @@ const eachSeries = require('async/eachSeries')
6const fs = require('fs') 6const fs = require('fs')
7const mongoose = require('mongoose') 7const mongoose = require('mongoose')
8const request = require('request') 8const request = require('request')
9const urlUtil = require('url')
10const waterfall = require('async/waterfall') 9const waterfall = require('async/waterfall')
11 10
12const constants = require('../initializers/constants') 11const constants = require('../initializers/constants')
@@ -44,7 +43,7 @@ function getMyCertificate (callback) {
44 fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback) 43 fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback)
45} 44}
46 45
47function makeFriends (urls, callback) { 46function makeFriends (hosts, callback) {
48 const podsScore = {} 47 const podsScore = {}
49 48
50 logger.info('Make friends!') 49 logger.info('Make friends!')
@@ -54,13 +53,13 @@ function makeFriends (urls, callback) {
54 return callback(err) 53 return callback(err)
55 } 54 }
56 55
57 eachSeries(urls, function (url, callbackEach) { 56 eachSeries(hosts, function (host, callbackEach) {
58 computeForeignPodsList(url, podsScore, callbackEach) 57 computeForeignPodsList(host, podsScore, callbackEach)
59 }, function (err) { 58 }, function (err) {
60 if (err) return callback(err) 59 if (err) return callback(err)
61 60
62 logger.debug('Pods scores computed.', { podsScore: podsScore }) 61 logger.debug('Pods scores computed.', { podsScore: podsScore })
63 const podsList = computeWinningPods(urls, podsScore) 62 const podsList = computeWinningPods(hosts, podsScore)
64 logger.debug('Pods that we keep.', { podsToKeep: podsList }) 63 logger.debug('Pods that we keep.', { podsToKeep: podsList })
65 64
66 makeRequestsToWinningPods(cert, podsList, callback) 65 makeRequestsToWinningPods(cert, podsList, callback)
@@ -149,45 +148,45 @@ module.exports = friends
149 148
150// --------------------------------------------------------------------------- 149// ---------------------------------------------------------------------------
151 150
152function computeForeignPodsList (url, podsScore, callback) { 151function computeForeignPodsList (host, podsScore, callback) {
153 getForeignPodsList(url, function (err, foreignPodsList) { 152 getForeignPodsList(host, function (err, foreignPodsList) {
154 if (err) return callback(err) 153 if (err) return callback(err)
155 154
156 if (!foreignPodsList) foreignPodsList = [] 155 if (!foreignPodsList) foreignPodsList = []
157 156
158 // Let's give 1 point to the pod we ask the friends list 157 // Let's give 1 point to the pod we ask the friends list
159 foreignPodsList.push({ url: url }) 158 foreignPodsList.push({ host })
160 159
161 foreignPodsList.forEach(function (foreignPod) { 160 foreignPodsList.forEach(function (foreignPod) {
162 const foreignPodUrl = foreignPod.url 161 const foreignPodHost = foreignPod.host
163 162
164 if (podsScore[foreignPodUrl]) podsScore[foreignPodUrl]++ 163 if (podsScore[foreignPodHost]) podsScore[foreignPodHost]++
165 else podsScore[foreignPodUrl] = 1 164 else podsScore[foreignPodHost] = 1
166 }) 165 })
167 166
168 callback() 167 callback()
169 }) 168 })
170} 169}
171 170
172function computeWinningPods (urls, podsScore) { 171function computeWinningPods (hosts, podsScore) {
173 // Build the list of pods to add 172 // Build the list of pods to add
174 // Only add a pod if it exists in more than a half base pods 173 // Only add a pod if it exists in more than a half base pods
175 const podsList = [] 174 const podsList = []
176 const baseScore = urls.length / 2 175 const baseScore = hosts.length / 2
177 Object.keys(podsScore).forEach(function (podUrl) { 176 Object.keys(podsScore).forEach(function (podHost) {
178 // If the pod is not me and with a good score we add it 177 // If the pod is not me and with a good score we add it
179 if (isMe(podUrl) === false && podsScore[podUrl] > baseScore) { 178 if (isMe(podHost) === false && podsScore[podHost] > baseScore) {
180 podsList.push({ url: podUrl }) 179 podsList.push({ host: podHost })
181 } 180 }
182 }) 181 })
183 182
184 return podsList 183 return podsList
185} 184}
186 185
187function getForeignPodsList (url, callback) { 186function getForeignPodsList (host, callback) {
188 const path = '/api/' + constants.API_VERSION + '/pods' 187 const path = '/api/' + constants.API_VERSION + '/pods'
189 188
190 request.get(url + path, function (err, response, body) { 189 request.get(constants.REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
191 if (err) return callback(err) 190 if (err) return callback(err)
192 191
193 try { 192 try {
@@ -207,26 +206,26 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
207 206
208 eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) { 207 eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
209 const params = { 208 const params = {
210 url: pod.url + '/api/' + constants.API_VERSION + '/pods/', 209 url: constants.REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + constants.API_VERSION + '/pods/',
211 method: 'POST', 210 method: 'POST',
212 json: { 211 json: {
213 url: constants.CONFIG.WEBSERVER.URL, 212 host: constants.CONFIG.WEBSERVER.HOST,
214 publicKey: cert 213 publicKey: cert
215 } 214 }
216 } 215 }
217 216
218 requests.makeRetryRequest(params, function (err, res, body) { 217 requests.makeRetryRequest(params, function (err, res, body) {
219 if (err) { 218 if (err) {
220 logger.error('Error with adding %s pod.', pod.url, { error: err }) 219 logger.error('Error with adding %s pod.', pod.host, { error: err })
221 // Don't break the process 220 // Don't break the process
222 return callbackEach() 221 return callbackEach()
223 } 222 }
224 223
225 if (res.statusCode === 200) { 224 if (res.statusCode === 200) {
226 const podObj = new Pod({ url: pod.url, publicKey: body.cert }) 225 const podObj = new Pod({ host: pod.host, publicKey: body.cert })
227 podObj.save(function (err, podCreated) { 226 podObj.save(function (err, podCreated) {
228 if (err) { 227 if (err) {
229 logger.error('Cannot add friend %s pod.', pod.url, { error: err }) 228 logger.error('Cannot add friend %s pod.', pod.host, { error: err })
230 return callbackEach() 229 return callbackEach()
231 } 230 }
232 231
@@ -236,7 +235,7 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
236 return callbackEach() 235 return callbackEach()
237 }) 236 })
238 } else { 237 } else {
239 logger.error('Status not 200 for %s pod.', pod.url) 238 logger.error('Status not 200 for %s pod.', pod.host)
240 return callbackEach() 239 return callbackEach()
241 } 240 }
242 }) 241 })
@@ -268,14 +267,6 @@ function createRequest (type, endpoint, data, to) {
268 }) 267 })
269} 268}
270 269
271function isMe (url) { 270function isMe (host) {
272 const parsedUrl = urlUtil.parse(url) 271 return host === constants.CONFIG.WEBSERVER.HOST
273
274 const hostname = parsedUrl.hostname
275 const port = parseInt(parsedUrl.port)
276
277 const myHostname = constants.CONFIG.WEBSERVER.HOSTNAME
278 const myPort = constants.CONFIG.WEBSERVER.PORT
279
280 return hostname === myHostname && port === myPort
281} 272}
diff --git a/server/middlewares/pods.js b/server/middlewares/pods.js
index 6e0874a76..487ea1259 100644
--- a/server/middlewares/pods.js
+++ b/server/middlewares/pods.js
@@ -1,38 +1,36 @@
1'use strict' 1'use strict'
2 2
3const urlModule = require('url') 3const constants = require('../initializers/constants')
4
5const logger = require('../helpers/logger')
6 4
7const podsMiddleware = { 5const podsMiddleware = {
8 setBodyUrlsPort, 6 setBodyHostsPort,
9 setBodyUrlPort 7 setBodyHostPort
10} 8}
11 9
12function setBodyUrlsPort (req, res, next) { 10function setBodyHostsPort (req, res, next) {
13 for (let i = 0; i < req.body.urls.length; i++) { 11 for (let i = 0; i < req.body.hosts.length; i++) {
14 const urlWithPort = getUrlWithPort(req.body.urls[i]) 12 const hostWithPort = getHostWithPort(req.body.hosts[i])
15 13
16 // Problem with the url parsing? 14 // Problem with the url parsing?
17 if (urlWithPort === null) { 15 if (hostWithPort === null) {
18 return res.sendStatus(500) 16 return res.sendStatus(500)
19 } 17 }
20 18
21 req.body.urls[i] = urlWithPort 19 req.body.hosts[i] = hostWithPort
22 } 20 }
23 21
24 return next() 22 return next()
25} 23}
26 24
27function setBodyUrlPort (req, res, next) { 25function setBodyHostPort (req, res, next) {
28 const urlWithPort = getUrlWithPort(req.body.url) 26 const hostWithPort = getHostWithPort(req.body.host)
29 27
30 // Problem with the url parsing? 28 // Problem with the url parsing?
31 if (urlWithPort === null) { 29 if (hostWithPort === null) {
32 return res.sendStatus(500) 30 return res.sendStatus(500)
33 } 31 }
34 32
35 req.body.url = urlWithPort 33 req.body.host = hostWithPort
36 34
37 return next() 35 return next()
38} 36}
@@ -43,20 +41,16 @@ module.exports = podsMiddleware
43 41
44// --------------------------------------------------------------------------- 42// ---------------------------------------------------------------------------
45 43
46function getUrlWithPort (url) { 44function getHostWithPort (host) {
47 const urlObj = urlModule.parse(url) 45 const splitted = host.split(':')
48 46
49 // Add the port if it is not specified 47 console.log(splitted)
50 if (urlObj.port === null) { 48 // The port was not specified
51 if (urlObj.protocol === 'http:') { 49 if (splitted.length === 1) {
52 return url + ':80' 50 if (constants.REMOTE_SCHEME.HTTP === 'https') return host + ':443'
53 } else if (urlObj.protocol === 'https:') { 51
54 return url + ':443' 52 return host + ':80'
55 } else {
56 logger.error('Unknown url protocol: ' + urlObj.protocol)
57 return null
58 }
59 } 53 }
60 54
61 return url 55 return host
62} 56}
diff --git a/server/middlewares/secure.js b/server/middlewares/secure.js
index 58f824d14..fd5bc51d6 100644
--- a/server/middlewares/secure.js
+++ b/server/middlewares/secure.js
@@ -12,27 +12,27 @@ const secureMiddleware = {
12} 12}
13 13
14function checkSignature (req, res, next) { 14function checkSignature (req, res, next) {
15 const url = req.body.signature.url 15 const host = req.body.signature.host
16 Pod.loadByUrl(url, function (err, pod) { 16 Pod.loadByHost(host, function (err, pod) {
17 if (err) { 17 if (err) {
18 logger.error('Cannot get signed url in decryptBody.', { error: err }) 18 logger.error('Cannot get signed host in decryptBody.', { error: err })
19 return res.sendStatus(500) 19 return res.sendStatus(500)
20 } 20 }
21 21
22 if (pod === null) { 22 if (pod === null) {
23 logger.error('Unknown pod %s.', url) 23 logger.error('Unknown pod %s.', host)
24 return res.sendStatus(403) 24 return res.sendStatus(403)
25 } 25 }
26 26
27 logger.debug('Decrypting body from %s.', url) 27 logger.debug('Decrypting body from %s.', host)
28 28
29 const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, url, req.body.signature.signature) 29 const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, host, req.body.signature.signature)
30 30
31 if (signatureOk === true) { 31 if (signatureOk === true) {
32 return next() 32 return next()
33 } 33 }
34 34
35 logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url) 35 logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.host)
36 return res.sendStatus(403) 36 return res.sendStatus(403)
37 }) 37 })
38} 38}
diff --git a/server/middlewares/validators/pods.js b/server/middlewares/validators/pods.js
index fd3d1e2f2..4f8bad2f9 100644
--- a/server/middlewares/validators/pods.js
+++ b/server/middlewares/validators/pods.js
@@ -10,7 +10,7 @@ const validatorsPod = {
10} 10}
11 11
12function makeFriends (req, res, next) { 12function makeFriends (req, res, next) {
13 req.checkBody('urls', 'Should have an array of unique urls').isEachUniqueUrlValid() 13 req.checkBody('hosts', 'Should have an array of unique hosts').isEachUniqueHostValid()
14 14
15 logger.debug('Checking makeFriends parameters', { parameters: req.body }) 15 logger.debug('Checking makeFriends parameters', { parameters: req.body })
16 16
@@ -32,7 +32,7 @@ function makeFriends (req, res, next) {
32} 32}
33 33
34function podsAdd (req, res, next) { 34function podsAdd (req, res, next) {
35 req.checkBody('url', 'Should have an url').notEmpty().isURL({ require_protocol: true }) 35 req.checkBody('host', 'Should have an host').notEmpty().isURL()
36 req.checkBody('publicKey', 'Should have a public key').notEmpty() 36 req.checkBody('publicKey', 'Should have a public key').notEmpty()
37 37
38 // TODO: check we don't have it already 38 // TODO: check we don't have it already
diff --git a/server/middlewares/validators/remote.js b/server/middlewares/validators/remote.js
index 8c29ef8ca..c6455e678 100644
--- a/server/middlewares/validators/remote.js
+++ b/server/middlewares/validators/remote.js
@@ -27,10 +27,10 @@ function remoteVideos (req, res, next) {
27} 27}
28 28
29function signature (req, res, next) { 29function signature (req, res, next) {
30 req.checkBody('signature.url', 'Should have a signature url').isURL() 30 req.checkBody('signature.host', 'Should have a signature host').isURL()
31 req.checkBody('signature.signature', 'Should have a signature').notEmpty() 31 req.checkBody('signature.signature', 'Should have a signature').notEmpty()
32 32
33 logger.debug('Checking signature parameters', { parameters: { signatureUrl: req.body.signature.url } }) 33 logger.debug('Checking signature parameters', { parameters: { signatureHost: req.body.signature.host } })
34 34
35 checkErrors(req, res, next) 35 checkErrors(req, res, next)
36} 36}
diff --git a/server/models/pods.js b/server/models/pods.js
index 6ab018c1c..49c73472a 100644
--- a/server/models/pods.js
+++ b/server/models/pods.js
@@ -12,7 +12,7 @@ const Video = mongoose.model('Video')
12// --------------------------------------------------------------------------- 12// ---------------------------------------------------------------------------
13 13
14const PodSchema = mongoose.Schema({ 14const PodSchema = mongoose.Schema({
15 url: String, 15 host: String,
16 publicKey: String, 16 publicKey: String,
17 score: { type: Number, max: constants.FRIEND_SCORE.MAX }, 17 score: { type: Number, max: constants.FRIEND_SCORE.MAX },
18 createdDate: { 18 createdDate: {
@@ -21,8 +21,7 @@ const PodSchema = mongoose.Schema({
21 } 21 }
22}) 22})
23 23
24// TODO: set options (TLD...) 24PodSchema.path('host').validate(validator.isURL)
25PodSchema.path('url').validate(validator.isURL)
26PodSchema.path('publicKey').required(true) 25PodSchema.path('publicKey').required(true)
27PodSchema.path('score').validate(function (value) { return !isNaN(value) }) 26PodSchema.path('score').validate(function (value) { return !isNaN(value) })
28 27
@@ -37,14 +36,14 @@ PodSchema.statics = {
37 listAllIds, 36 listAllIds,
38 listBadPods, 37 listBadPods,
39 load, 38 load,
40 loadByUrl, 39 loadByHost,
41 removeAll 40 removeAll
42} 41}
43 42
44PodSchema.pre('save', function (next) { 43PodSchema.pre('save', function (next) {
45 const self = this 44 const self = this
46 45
47 Pod.loadByUrl(this.url, function (err, pod) { 46 Pod.loadByHost(this.host, function (err, pod) {
48 if (err) return next(err) 47 if (err) return next(err)
49 48
50 if (pod) return next(new Error('Pod already exists.')) 49 if (pod) return next(new Error('Pod already exists.'))
@@ -56,7 +55,7 @@ PodSchema.pre('save', function (next) {
56 55
57PodSchema.pre('remove', function (next) { 56PodSchema.pre('remove', function (next) {
58 // Remove the videos owned by this pod too 57 // Remove the videos owned by this pod too
59 Video.listByUrl(this.url, function (err, videos) { 58 Video.listByHost(this.host, function (err, videos) {
60 if (err) return next(err) 59 if (err) return next(err)
61 60
62 each(videos, function (video, callbackEach) { 61 each(videos, function (video, callbackEach) {
@@ -72,7 +71,7 @@ const Pod = mongoose.model('Pod', PodSchema)
72function toFormatedJSON () { 71function toFormatedJSON () {
73 const json = { 72 const json = {
74 id: this._id, 73 id: this._id,
75 url: this.url, 74 host: this.host,
76 score: this.score, 75 score: this.score,
77 createdDate: this.createdDate 76 createdDate: this.createdDate
78 } 77 }
@@ -111,8 +110,8 @@ function load (id, callback) {
111 return this.findById(id, callback) 110 return this.findById(id, callback)
112} 111}
113 112
114function loadByUrl (url, callback) { 113function loadByHost (host, callback) {
115 return this.findOne({ url: url }, callback) 114 return this.findOne({ host }, callback)
116} 115}
117 116
118function removeAll (callback) { 117function removeAll (callback) {
diff --git a/server/models/request.js b/server/models/request.js
index f5eec2134..59bf440fe 100644
--- a/server/models/request.js
+++ b/server/models/request.js
@@ -121,7 +121,7 @@ function makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
121 if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) { 121 if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) {
122 logger.error( 122 logger.error(
123 'Error sending secure request to %s pod.', 123 'Error sending secure request to %s pod.',
124 toPod.url, 124 toPod.host,
125 { 125 {
126 error: err || new Error('Status code not 20x : ' + res.statusCode) 126 error: err || new Error('Status code not 20x : ' + res.statusCode)
127 } 127 }
diff --git a/server/models/video.js b/server/models/video.js
index 0da2cb8ab..6d3fa3fb8 100644
--- a/server/models/video.js
+++ b/server/models/video.js
@@ -28,10 +28,9 @@ const VideoSchema = mongoose.Schema({
28 magnet: { 28 magnet: {
29 infoHash: String 29 infoHash: String
30 }, 30 },
31 podUrl: String, 31 podHost: String,
32 author: String, 32 author: String,
33 duration: Number, 33 duration: Number,
34 thumbnail: String,
35 tags: [ String ], 34 tags: [ String ],
36 createdDate: { 35 createdDate: {
37 type: Date, 36 type: Date,
@@ -41,14 +40,9 @@ const VideoSchema = mongoose.Schema({
41 40
42VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid) 41VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid)
43VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid) 42VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid)
44VideoSchema.path('podUrl').validate(customVideosValidators.isVideoPodUrlValid) 43VideoSchema.path('podHost').validate(customVideosValidators.isVideoPodHostValid)
45VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid) 44VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid)
46VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid) 45VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid)
47// The tumbnail can be the path or the data in base 64
48// The pre save hook will convert the base 64 data in a file on disk and replace the thumbnail key by the filename
49VideoSchema.path('thumbnail').validate(function (value) {
50 return customVideosValidators.isVideoThumbnailValid(value) || customVideosValidators.isVideoThumbnail64Valid(value)
51})
52VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid) 46VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid)
53 47
54VideoSchema.methods = { 48VideoSchema.methods = {
@@ -65,8 +59,8 @@ VideoSchema.methods = {
65VideoSchema.statics = { 59VideoSchema.statics = {
66 getDurationFromFile, 60 getDurationFromFile,
67 listForApi, 61 listForApi,
68 listByUrlAndRemoteId, 62 listByHostAndRemoteId,
69 listByUrl, 63 listByHost,
70 listOwned, 64 listOwned,
71 listOwnedByAuthor, 65 listOwnedByAuthor,
72 listRemotes, 66 listRemotes,
@@ -107,7 +101,7 @@ VideoSchema.pre('save', function (next) {
107 101
108 if (video.isOwned()) { 102 if (video.isOwned()) {
109 const videoPath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) 103 const videoPath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
110 this.podUrl = constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT 104 this.podHost = constants.CONFIG.WEBSERVER.HOST
111 105
112 tasks.push( 106 tasks.push(
113 // TODO: refractoring 107 // TODO: refractoring
@@ -160,8 +154,8 @@ function generateMagnetUri () {
160 baseUrlHttp = constants.CONFIG.WEBSERVER.URL 154 baseUrlHttp = constants.CONFIG.WEBSERVER.URL
161 baseUrlWs = constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT 155 baseUrlWs = constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
162 } else { 156 } else {
163 baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.podUrl 157 baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.podHost
164 baseUrlWs = constants.REMOTE_SCHEME.WS + this.podUrl 158 baseUrlWs = constants.REMOTE_SCHEME.WS + this.podHost
165 } 159 }
166 160
167 const xs = baseUrlHttp + constants.STATIC_PATHS.TORRENTS + this.getTorrentName() 161 const xs = baseUrlHttp + constants.STATIC_PATHS.TORRENTS + this.getTorrentName()
@@ -215,7 +209,7 @@ function toFormatedJSON () {
215 id: this._id, 209 id: this._id,
216 name: this.name, 210 name: this.name,
217 description: this.description, 211 description: this.description,
218 podUrl: this.podUrl, 212 podHost: this.podHost,
219 isLocal: this.isOwned(), 213 isLocal: this.isOwned(),
220 magnetUri: this.generateMagnetUri(), 214 magnetUri: this.generateMagnetUri(),
221 author: this.author, 215 author: this.author,
@@ -249,7 +243,7 @@ function toRemoteJSON (callback) {
249 thumbnailBase64: new Buffer(thumbnailData).toString('base64'), 243 thumbnailBase64: new Buffer(thumbnailData).toString('base64'),
250 tags: self.tags, 244 tags: self.tags,
251 createdDate: self.createdDate, 245 createdDate: self.createdDate,
252 podUrl: self.podUrl 246 podHost: self.podHost
253 } 247 }
254 248
255 return callback(null, remoteVideo) 249 return callback(null, remoteVideo)
@@ -271,12 +265,12 @@ function listForApi (start, count, sort, callback) {
271 return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback) 265 return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
272} 266}
273 267
274function listByUrlAndRemoteId (fromUrl, remoteId, callback) { 268function listByHostAndRemoteId (fromHost, remoteId, callback) {
275 this.find({ podUrl: fromUrl, remoteId: remoteId }, callback) 269 this.find({ podHost: fromHost, remoteId: remoteId }, callback)
276} 270}
277 271
278function listByUrl (fromUrl, callback) { 272function listByHost (fromHost, callback) {
279 this.find({ podUrl: fromUrl }, callback) 273 this.find({ podHost: fromHost }, callback)
280} 274}
281 275
282function listOwned (callback) { 276function listOwned (callback) {