| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | const async = require('async'); | 
					
						
							|  |  |  | const	assert = require('assert'); | 
					
						
							|  |  |  | const nconf = require('nconf'); | 
					
						
							|  |  |  | const path = require('path'); | 
					
						
							|  |  |  | const request = require('request'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const db = require('./mocks/databasemock'); | 
					
						
							|  |  |  | const categories = require('../src/categories'); | 
					
						
							|  |  |  | const topics = require('../src/topics'); | 
					
						
							|  |  |  | const user = require('../src/user'); | 
					
						
							|  |  |  | const groups = require('../src/groups'); | 
					
						
							|  |  |  | const privileges = require('../src/privileges'); | 
					
						
							|  |  |  | const meta = require('../src/meta'); | 
					
						
							|  |  |  | const socketUser = require('../src/socket.io/user'); | 
					
						
							|  |  |  | const helpers = require('./helpers'); | 
					
						
							|  |  |  | const file = require('../src/file'); | 
					
						
							|  |  |  | const image = require('../src/image'); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | describe('Upload Controllers', () => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 	let tid; | 
					
						
							|  |  |  | 	let cid; | 
					
						
							|  |  |  | 	let pid; | 
					
						
							|  |  |  | 	let adminUid; | 
					
						
							|  |  |  | 	let regularUid; | 
					
						
							| 
									
										
										
										
											2021-04-18 19:03:35 -04:00
										 |  |  | 	let maliciousUid; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 	before((done) => { | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 		async.series({ | 
					
						
							|  |  |  | 			category: function (next) { | 
					
						
							|  |  |  | 				categories.create({ | 
					
						
							|  |  |  | 					name: 'Test Category', | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 					description: 'Test category created by testing script', | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				}, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			adminUid: function (next) { | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 				user.create({ username: 'admin', password: 'barbar' }, next); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			regularUid: function (next) { | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 				user.create({ username: 'regular', password: 'zugzug' }, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2021-04-18 19:03:35 -04:00
										 |  |  | 			maliciousUid: function (next) { | 
					
						
							|  |  |  | 				user.create({ username: 'malicioususer', password: 'herpderp' }, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		}, (err, results) => { | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return done(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			adminUid = results.adminUid; | 
					
						
							|  |  |  | 			regularUid = results.regularUid; | 
					
						
							| 
									
										
										
										
											2021-04-18 19:03:35 -04:00
										 |  |  | 			maliciousUid = results.maliciousUid; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 			cid = results.category.cid; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 			topics.post({ uid: adminUid, title: 'test topic title', content: 'test topic content', cid: results.category.cid }, (err, result) => { | 
					
						
							| 
									
										
										
										
											2020-01-19 14:57:06 -05:00
										 |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return done(err); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				tid = result.topicData.tid; | 
					
						
							|  |  |  | 				pid = result.postData.pid; | 
					
						
							| 
									
										
										
										
											2020-01-19 14:57:06 -05:00
										 |  |  | 				groups.join('administrators', adminUid, done); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 	describe('regular user uploads', () => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 		let jar; | 
					
						
							|  |  |  | 		let csrf_token; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		before((done) => { | 
					
						
							|  |  |  | 			helpers.loginUser('regular', 'zugzug', (err, _jar, _csrf_token) => { | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				jar = _jar; | 
					
						
							|  |  |  | 				csrf_token = _csrf_token; | 
					
						
							| 
									
										
										
										
											2020-05-26 21:57:38 -04:00
										 |  |  | 				privileges.global.give(['groups:upload:post:file'], 'registered-users', done); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload an image to a post', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 				assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 				assert(body.response.images[0].url); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload an image to a post and then delete the upload', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2018-05-26 12:49:29 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 				assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 				assert(body.response.images[0].url); | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 				const name = body.response.images[0].url.replace(nconf.get('relative_path') + nconf.get('upload_url'), ''); | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 				socketUser.deleteUpload({ uid: regularUid }, { uid: regularUid, name: name }, (err) => { | 
					
						
							| 
									
										
										
										
											2018-05-26 12:49:29 -04:00
										 |  |  | 					assert.ifError(err); | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 					db.getSortedSetRange(`uid:${regularUid}:uploads`, 0, -1, (err, uploads) => { | 
					
						
							| 
									
										
										
										
											2018-05-26 12:49:29 -04:00
										 |  |  | 						assert.ifError(err); | 
					
						
							|  |  |  | 						assert.equal(uploads.includes(name), false); | 
					
						
							|  |  |  | 						done(); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow deleting if path is not correct', (done) => { | 
					
						
							|  |  |  | 			socketUser.deleteUpload({ uid: adminUid }, { uid: regularUid, name: '../../bkconfig.json' }, (err) => { | 
					
						
							| 
									
										
										
										
											2020-01-19 14:57:06 -05:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-path]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow deleting if path is not correct', (done) => { | 
					
						
							|  |  |  | 			socketUser.deleteUpload({ uid: adminUid }, { uid: regularUid, name: '/files/../../bkconfig.json' }, (err) => { | 
					
						
							| 
									
										
										
										
											2020-01-19 14:57:06 -05:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-path]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should resize and upload an image to a post', (done) => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 			const oldValue = meta.config.resizeImageWidth; | 
					
						
							| 
									
										
										
										
											2018-10-24 20:03:03 -04:00
										 |  |  | 			meta.config.resizeImageWidth = 10; | 
					
						
							|  |  |  | 			meta.config.resizeImageWidthThreshold = 10; | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-02-24 17:34:34 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 				assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 				assert(body.response.images[0].url); | 
					
						
							|  |  |  | 				assert(body.response.images[0].url.match(/\/assets\/uploads\/files\/\d+-test-resized\.png/)); | 
					
						
							| 
									
										
										
										
											2018-10-24 20:03:03 -04:00
										 |  |  | 				meta.config.resizeImageWidth = oldValue; | 
					
						
							|  |  |  | 				meta.config.resizeImageWidthThreshold = 1520; | 
					
						
							| 
									
										
										
										
											2017-02-24 17:34:34 +03:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload a file to a post', (done) => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 			const oldValue = meta.config.allowedFileExtensions; | 
					
						
							| 
									
										
										
										
											2017-04-14 13:38:58 -04:00
										 |  |  | 			meta.config.allowedFileExtensions = 'png,jpg,bmp,html'; | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/503.html'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-04-14 13:38:58 -04:00
										 |  |  | 				meta.config.allowedFileExtensions = oldValue; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 				assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 				assert(body.response.images[0].url); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-18 19:19:52 -04:00
										 |  |  | 		it('should fail to upload image to post if image is broken', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/brokenimage.png'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							|  |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.strictEqual(res.statusCode, 500); | 
					
						
							|  |  |  | 				assert(body && body.status && body.status.message); | 
					
						
							|  |  |  | 				assert(body.status.message.startsWith('Input file has corrupt header: pngload: end of stream')); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail to upload image to post if image dimensions are too big', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/toobig.jpg'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2018-09-20 17:05:52 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(res.statusCode, 500); | 
					
						
							|  |  |  | 				assert(body && body.status && body.status.message); | 
					
						
							|  |  |  | 				assert.strictEqual(body.status.message, 'Input image exceeds pixel limit'); | 
					
						
							| 
									
										
										
										
											2018-09-20 17:05:52 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail if file is not an image', (done) => { | 
					
						
							|  |  |  | 			image.isFileTypeAllowed(path.join(__dirname, '../test/files/notanimage.png'), (err) => { | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(err.message, 'Input file contains unsupported image format'); | 
					
						
							| 
									
										
										
										
											2018-09-20 17:05:52 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail if file is not an image', (done) => { | 
					
						
							|  |  |  | 			image.isFileTypeAllowed(path.join(__dirname, '../test/files/notanimage.png'), (err) => { | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(err.message, 'Input file contains unsupported image format'); | 
					
						
							| 
									
										
										
										
											2019-09-29 19:53:03 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail if file is not an image', (done) => { | 
					
						
							|  |  |  | 			image.size(path.join(__dirname, '../test/files/notanimage.png'), (err) => { | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(err.message, 'Input file contains unsupported image format'); | 
					
						
							| 
									
										
										
										
											2019-01-19 12:44:14 -05:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail if file is missing', (done) => { | 
					
						
							|  |  |  | 			image.size(path.join(__dirname, '../test/files/doesnotexist.png'), (err) => { | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 				assert.strictEqual(err.message, 'Input file is missing'); | 
					
						
							| 
									
										
										
										
											2018-09-20 17:05:52 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 		// it('should fail if topic thumbs are disabled', function (done) {
 | 
					
						
							| 
									
										
										
										
											2021-02-04 02:07:29 -07:00
										 |  |  | 		// 	helpers.uploadFile(
 | 
					
						
							|  |  |  | 		// 		nconf.get('url') + '/api/topic/thumb/upload',
 | 
					
						
							|  |  |  | 		// 		path.join(__dirname, '../test/files/test.png'),
 | 
					
						
							|  |  |  | 		// 		{}, jar, csrf_token,
 | 
					
						
							|  |  |  | 		// 		function (err, res, body) {
 | 
					
						
							|  |  |  | 		// 			assert.ifError(err);
 | 
					
						
							|  |  |  | 		// 			assert.strictEqual(res.statusCode, 404);
 | 
					
						
							|  |  |  | 		// 			console.log(body);
 | 
					
						
							|  |  |  | 		// 			assert(body && body.status && body.status.code);
 | 
					
						
							|  |  |  | 		// 			assert.strictEqual(body.status.code, '[[error:topic-thumbnails-are-disabled]]');
 | 
					
						
							|  |  |  | 		// 			done();
 | 
					
						
							|  |  |  | 		// 		}
 | 
					
						
							|  |  |  | 		// 	);
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 		// });
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// it('should fail if file is not image', function (done) {
 | 
					
						
							|  |  |  | 		// 	meta.config.allowTopicsThumbnail = 1;
 | 
					
						
							| 
									
										
										
										
											2021-02-04 02:07:29 -07:00
										 |  |  | 		// 	helpers.uploadFile(
 | 
					
						
							|  |  |  | 		// 		nconf.get('url') + '/api/topic/thumb/upload',
 | 
					
						
							|  |  |  | 		// 		path.join(__dirname, '../test/files/503.html'),
 | 
					
						
							|  |  |  | 		// 		{}, jar, csrf_token,
 | 
					
						
							|  |  |  | 		// 		function (err, res, body) {
 | 
					
						
							|  |  |  | 		// 			assert.ifError(err);
 | 
					
						
							|  |  |  | 		// 			assert.equal(res.statusCode, 500);
 | 
					
						
							|  |  |  | 		// 			assert.equal(body.error, '[[error:invalid-file]]');
 | 
					
						
							|  |  |  | 		// 			done();
 | 
					
						
							|  |  |  | 		// 		}
 | 
					
						
							|  |  |  | 		// 	);
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 		// });
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// it('should upload topic thumb', function (done) {
 | 
					
						
							|  |  |  | 		// 	meta.config.allowTopicsThumbnail = 1;
 | 
					
						
							| 
									
										
										
										
											2021-02-04 02:07:29 -07:00
										 |  |  | 		// 	helpers.uploadFile(
 | 
					
						
							|  |  |  | 		// 		nconf.get('url') + '/api/topic/thumb/upload',
 | 
					
						
							|  |  |  | 		// 		path.join(__dirname, '../test/files/test.png'),
 | 
					
						
							|  |  |  | 		// 		{}, jar, csrf_token,
 | 
					
						
							|  |  |  | 		// 		function (err, res, body) {
 | 
					
						
							|  |  |  | 		// 			assert.ifError(err);
 | 
					
						
							|  |  |  | 		// 			assert.equal(res.statusCode, 200);
 | 
					
						
							|  |  |  | 		// 			assert(Array.isArray(body));
 | 
					
						
							|  |  |  | 		// 			assert(body[0].path);
 | 
					
						
							|  |  |  | 		// 			assert(body[0].url);
 | 
					
						
							|  |  |  | 		// 			done();
 | 
					
						
							|  |  |  | 		// 		}
 | 
					
						
							|  |  |  | 		// 	);
 | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 		// });
 | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow non image uploads', (done) => { | 
					
						
							|  |  |  | 			socketUser.updateCover({ uid: 1 }, { uid: 1, file: { path: '../../text.txt' } }, (err) => { | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-data]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow non image uploads', (done) => { | 
					
						
							|  |  |  | 			socketUser.updateCover({ uid: 1 }, { uid: 1, imageData: 'data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+' }, (err) => { | 
					
						
							| 
									
										
										
										
											2017-10-31 18:03:54 -04:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-image]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow svg uploads', (done) => { | 
					
						
							|  |  |  | 			socketUser.updateCover({ uid: 1 }, { uid: 1, imageData: 'data:image/svg;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+' }, (err) => { | 
					
						
							| 
									
										
										
										
											2019-09-21 23:10:49 -04:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-image]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow non image uploads', (done) => { | 
					
						
							|  |  |  | 			socketUser.uploadCroppedPicture({ uid: 1 }, { uid: 1, file: { path: '../../text.txt' } }, (err) => { | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-data]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow non image uploads', (done) => { | 
					
						
							|  |  |  | 			socketUser.uploadCroppedPicture({ uid: 1 }, { uid: 1, imageData: 'data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+' }, (err) => { | 
					
						
							| 
									
										
										
										
											2017-10-31 18:03:54 -04:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-image]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should not allow svg uploads', (done) => { | 
					
						
							|  |  |  | 			socketUser.uploadCroppedPicture({ uid: 1 }, { uid: 1, imageData: 'data:image/svg;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+' }, (err) => { | 
					
						
							| 
									
										
										
										
											2019-09-21 23:10:49 -04:00
										 |  |  | 				assert.equal(err.message, '[[error:invalid-image]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should delete users uploads if account is deleted', (done) => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 			let jar; | 
					
						
							|  |  |  | 			let uid; | 
					
						
							|  |  |  | 			let url; | 
					
						
							|  |  |  | 			const file = require('../src/file'); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			async.waterfall([ | 
					
						
							|  |  |  | 				function (next) { | 
					
						
							|  |  |  | 					user.create({ username: 'uploader', password: 'barbar' }, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (_uid, next) { | 
					
						
							|  |  |  | 					uid = _uid; | 
					
						
							|  |  |  | 					helpers.loginUser('uploader', 'barbar', next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (jar, csrf_token, next) { | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 					helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, next); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 				function (res, body, next) { | 
					
						
							| 
									
										
										
										
											2020-12-04 16:31:35 -05:00
										 |  |  | 					assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 					assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 					assert(body.response.images[0].url); | 
					
						
							|  |  |  | 					url = body.response.images[0].url; | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					user.delete(1, uid, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2018-10-04 11:08:01 -04:00
										 |  |  | 				function (userData, next) { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 					const filePath = path.join(nconf.get('upload_path'), url.replace('/assets/uploads', '')); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 					file.exists(filePath, next); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				function (exists, next) { | 
					
						
							|  |  |  | 					assert(!exists); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			], done); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2017-10-31 18:03:54 -04:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-18 19:03:35 -04:00
										 |  |  | 	describe('regular user uploads rate limits', () => { | 
					
						
							|  |  |  | 		let jar; | 
					
						
							|  |  |  | 		let csrf_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		before((done) => { | 
					
						
							|  |  |  | 			helpers.loginUser('malicioususer', 'herpderp', (err, _jar, _csrf_token) => { | 
					
						
							|  |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				jar = _jar; | 
					
						
							|  |  |  | 				csrf_token = _csrf_token; | 
					
						
							|  |  |  | 				privileges.global.give(['groups:upload:post:file'], 'registered-users', done); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		it('should fail if the user exceeds the upload rate limit threshold', (done) => { | 
					
						
							|  |  |  | 			const oldValue = meta.config.allowedFileExtensions; | 
					
						
							|  |  |  | 			meta.config.allowedFileExtensions = 'png,jpg,bmp,html'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// why / 2? see: helpers.uploadFile for a weird quirk where we actually upload 2 files per upload in our tests.
 | 
					
						
							|  |  |  | 			async.times(meta.config.uploadRateLimitThreshold / 2, (i, next) => { | 
					
						
							|  |  |  | 				helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/503.html'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							|  |  |  | 					if (i + 1 > meta.config.uploadRateLimitThreshold / 2) { | 
					
						
							|  |  |  | 						assert.strictEqual(res.statusCode, 500); | 
					
						
							|  |  |  | 						assert.strictEqual(body.error, '[[error:upload-ratelimit-reached]]'); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						assert.ifError(err); | 
					
						
							|  |  |  | 						assert.strictEqual(res.statusCode, 200); | 
					
						
							|  |  |  | 						assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 						assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 						assert(body.response.images[0].url); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					next(err); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}, (err) => { | 
					
						
							|  |  |  | 				meta.config.allowedFileExtensions = oldValue; | 
					
						
							|  |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 	describe('admin uploads', () => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 		let jar; | 
					
						
							|  |  |  | 		let csrf_token; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		before((done) => { | 
					
						
							|  |  |  | 			helpers.loginUser('admin', 'barbar', (err, _jar, _csrf_token) => { | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				jar = _jar; | 
					
						
							|  |  |  | 				csrf_token = _csrf_token; | 
					
						
							| 
									
										
										
										
											2020-01-19 14:57:06 -05:00
										 |  |  | 				done(); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload site logo', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadlogo`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(Array.isArray(body)); | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 				assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/system/site-logo.png`); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail to upload invalid file type', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/503.html'), { params: JSON.stringify({ cid: cid }) }, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-05-10 15:34:36 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(body.error, '[[error:invalid-image-type, image/png, image/jpeg, image/pjpeg, image/jpg, image/gif, image/svg+xml]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail to upload category image with invalid json params', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/test.png'), { params: 'invalid json' }, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-05-10 15:34:36 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							| 
									
										
										
										
											2017-05-10 15:51:19 -04:00
										 |  |  | 				assert.equal(body.error, '[[error:invalid-json]]'); | 
					
						
							| 
									
										
										
										
											2017-05-10 15:34:36 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload category image', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/test.png'), { params: JSON.stringify({ cid: cid }) }, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(Array.isArray(body)); | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 				assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/category/category-1.png`); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload default avatar', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadDefaultAvatar`, path.join(__dirname, '../test/files/test.png'), { }, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-05-10 16:27:44 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 				assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/system/avatar-default.png`); | 
					
						
							| 
									
										
										
										
											2017-05-10 16:27:44 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload og image', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadOgImage`, path.join(__dirname, '../test/files/test.png'), { }, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-05-10 16:27:44 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 				assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/system/og-image.png`); | 
					
						
							| 
									
										
										
										
											2017-05-10 16:27:44 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload favicon', (done) => { | 
					
						
							|  |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadfavicon`, path.join(__dirname, '../test/files/favicon.ico'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(Array.isArray(body)); | 
					
						
							| 
									
										
										
										
											2017-02-08 11:41:24 -07:00
										 |  |  | 				assert.equal(body[0].url, '/assets/uploads/system/favicon.ico'); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload touch icon', (done) => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 			const touchiconAssetPath = '/assets/uploads/system/touchicon-orig.png'; | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadTouchIcon`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(Array.isArray(body)); | 
					
						
							| 
									
										
										
										
											2017-06-28 15:02:17 +02:00
										 |  |  | 				assert.equal(body[0].url, touchiconAssetPath); | 
					
						
							|  |  |  | 				meta.config['brand:touchIcon'] = touchiconAssetPath; | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 				request(`${nconf.get('url')}/apple-touch-icon`, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2017-06-28 15:02:17 +02:00
										 |  |  | 					assert.ifError(err); | 
					
						
							|  |  |  | 					assert.equal(res.statusCode, 200); | 
					
						
							|  |  |  | 					assert(body); | 
					
						
							|  |  |  | 					done(); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should upload regular file', (done) => { | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/upload/file`, path.join(__dirname, '../test/files/test.png'), { | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 				params: JSON.stringify({ | 
					
						
							|  |  |  | 					folder: 'system', | 
					
						
							|  |  |  | 				}), | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 			}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 200); | 
					
						
							|  |  |  | 				assert(Array.isArray(body)); | 
					
						
							|  |  |  | 				assert.equal(body[0].url, '/assets/uploads/system/test.png'); | 
					
						
							|  |  |  | 				assert(file.existsSync(path.join(nconf.get('upload_path'), 'system', 'test.png'))); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 		it('should fail to upload regular file in wrong directory', (done) => { | 
					
						
							| 
									
										
										
										
											2021-02-03 23:59:08 -07:00
										 |  |  | 			helpers.uploadFile(`${nconf.get('url')}/api/admin/upload/file`, path.join(__dirname, '../test/files/test.png'), { | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 				params: JSON.stringify({ | 
					
						
							|  |  |  | 					folder: '../../system', | 
					
						
							|  |  |  | 				}), | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 			}, jar, csrf_token, (err, res, body) => { | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 				assert.ifError(err); | 
					
						
							|  |  |  | 				assert.equal(res.statusCode, 500); | 
					
						
							|  |  |  | 				assert.strictEqual(body.error, '[[error:invalid-path]]'); | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 	}); | 
					
						
							|  |  |  | }); |