| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | const async = require('async'); | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | const assert = require('assert'); | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | const nconf = require('nconf'); | 
					
						
							|  |  |  | const path = require('path'); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | const fs = require('fs').promises; | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | const db = require('./mocks/databasemock'); | 
					
						
							|  |  |  | const categories = require('../src/categories'); | 
					
						
							|  |  |  | const topics = require('../src/topics'); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | const posts = require('../src/posts'); | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 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'); | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | const request = require('../src/request'); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | const emptyUploadsFolder = async () => { | 
					
						
							|  |  |  | 	const files = await fs.readdir(`${nconf.get('upload_path')}/files`); | 
					
						
							|  |  |  | 	await Promise.all(files.map(async (filename) => { | 
					
						
							|  |  |  | 		await file.delete(`${nconf.get('upload_path')}/files/${filename}`); | 
					
						
							|  |  |  | 	})); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-04-18 19:41:00 -04:00
										 |  |  | 	describe('regular user uploads rate limits', () => { | 
					
						
							|  |  |  | 		let jar; | 
					
						
							|  |  |  | 		let csrf_token; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-22 19:23:51 -05:00
										 |  |  | 		before(async () => { | 
					
						
							|  |  |  | 			({ jar, csrf_token } = await helpers.loginUser('malicioususer', 'herpderp')); | 
					
						
							|  |  |  | 			await privileges.global.give(['groups:upload:post:file'], 'registered-users'); | 
					
						
							| 
									
										
										
										
											2021-04-18 19:41:00 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should fail if the user exceeds the upload rate limit threshold', async () => { | 
					
						
							| 
									
										
										
										
											2021-04-18 19:41:00 -04:00
										 |  |  | 			const oldValue = meta.config.allowedFileExtensions; | 
					
						
							|  |  |  | 			meta.config.allowedFileExtensions = 'png,jpg,bmp,html'; | 
					
						
							| 
									
										
										
										
											2021-04-18 21:38:47 -04:00
										 |  |  | 			require('../src/middleware/uploads').clearCache(); | 
					
						
							| 
									
										
										
										
											2023-04-23 18:59:18 -04:00
										 |  |  | 			const times = meta.config.uploadRateLimitThreshold + 1; | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			for (let i = 0; i < times; i++) { | 
					
						
							|  |  |  | 				// eslint-disable-next-line no-await-in-loop
 | 
					
						
							|  |  |  | 				const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/503.html'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 				if (i + 1 >= times) { | 
					
						
							|  |  |  | 					assert.strictEqual(response.statusCode, 500); | 
					
						
							|  |  |  | 					assert.strictEqual(body.error, '[[error:upload-ratelimit-reached]]'); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					assert.strictEqual(response.statusCode, 200); | 
					
						
							|  |  |  | 					assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 					assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 					assert(body.response.images[0].url); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			meta.config.allowedFileExtensions = oldValue; | 
					
						
							| 
									
										
										
										
											2021-04-18 19:41:00 -04: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-11-22 19:23:51 -05:00
										 |  |  | 		before(async () => { | 
					
						
							| 
									
										
										
										
											2021-04-18 19:41:00 -04:00
										 |  |  | 			meta.config.uploadRateLimitThreshold = 1000; | 
					
						
							| 
									
										
										
										
											2021-11-22 19:23:51 -05:00
										 |  |  | 			({ jar, csrf_token } = await helpers.loginUser('regular', 'zugzug')); | 
					
						
							|  |  |  | 			await privileges.global.give(['groups:upload:post:file'], 'registered-users'); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload an image to a post', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.equal(response.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
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload an image to a post and then delete the upload', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.strictEqual(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 			assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 			assert(body.response.images[0].url); | 
					
						
							| 
									
										
										
										
											2025-04-04 10:45:05 -04:00
										 |  |  | 			const name = body.response.images[0].url.replace(`${nconf.get('relative_path') + nconf.get('upload_url')}`, ''); | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			await socketUser.deleteUpload({ uid: regularUid }, { uid: regularUid, name: name }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const uploads = await db.getSortedSetRange(`uid:${regularUid}:uploads`, 0, -1); | 
					
						
							|  |  |  | 			assert.equal(uploads.includes(name), false); | 
					
						
							| 
									
										
										
										
											2018-05-26 12:49:29 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should resize and upload an image to a post', async () => { | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			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/)); | 
					
						
							|  |  |  | 			meta.config.resizeImageWidth = oldValue; | 
					
						
							| 
									
										
										
										
											2024-11-07 10:57:22 -05:00
										 |  |  | 			meta.config.resizeImageWidthThreshold = 2000; | 
					
						
							| 
									
										
										
										
											2024-12-02 10:08:52 -05:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		it('should resize and upload an image to a post and replace original', async () => { | 
					
						
							|  |  |  | 			const oldValue = meta.config.resizeImageWidth; | 
					
						
							|  |  |  | 			const keepOldValue = meta.config.resizeImageKeepOriginal; | 
					
						
							|  |  |  | 			meta.config.resizeImageWidth = 10; | 
					
						
							|  |  |  | 			meta.config.resizeImageWidthThreshold = 10; | 
					
						
							|  |  |  | 			meta.config.resizeImageKeepOriginal = 0; | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			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.png/)); | 
					
						
							|  |  |  | 			meta.config.resizeImageWidth = oldValue; | 
					
						
							|  |  |  | 			meta.config.resizeImageWidthThreshold = 2000; | 
					
						
							|  |  |  | 			meta.config.resizeImageKeepOriginal = keepOldValue; | 
					
						
							| 
									
										
										
										
											2017-02-24 17:34:34 +03:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload a file to a post', async () => { | 
					
						
							| 
									
										
										
										
											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'; | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/503.html'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 			meta.config.allowedFileExtensions = oldValue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.strictEqual(response.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
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should fail to upload image to post if image dimensions are too big', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/toobig.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.strictEqual(response.statusCode, 500); | 
					
						
							|  |  |  | 			assert(body && body.status && body.status.message); | 
					
						
							|  |  |  | 			assert.strictEqual(body.status.message, 'Image dimensions are too big'); | 
					
						
							| 
									
										
										
										
											2021-04-18 19:19:52 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should fail to upload image to post if image is broken', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/brokenimage.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.strictEqual(response.statusCode, 500); | 
					
						
							|  |  |  | 			assert(body && body.status && body.status.message); | 
					
						
							| 
									
										
										
										
											2025-08-25 12:08:55 -04:00
										 |  |  | 			assert.strictEqual(body.status.message, 'pngload_buffer: end of stream'); | 
					
						
							| 
									
										
										
										
											2018-09-20 17:05:52 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) => { | 
					
						
							| 
									
										
										
										
											2022-04-19 13:17:03 -04:00
										 |  |  | 				assert(err.message.startsWith('Input file is missing')); | 
					
						
							| 
									
										
										
										
											2018-09-20 17:05:52 -04:00
										 |  |  | 				done(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should delete users uploads if account is deleted', async () => { | 
					
						
							|  |  |  | 			const uid = await user.create({ username: 'uploader', password: 'barbar' }); | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 			const file = require('../src/file'); | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			const data = await helpers.loginUser('uploader', 'barbar'); | 
					
						
							|  |  |  | 			const { body } = await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, data.jar, data.csrf_token); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			assert(body && body.status && body.response && body.response.images); | 
					
						
							|  |  |  | 			assert(Array.isArray(body.response.images)); | 
					
						
							|  |  |  | 			assert(body.response.images[0].url); | 
					
						
							|  |  |  | 			const { url } = body.response.images[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			await user.delete(1, uid); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			const filePath = path.join(nconf.get('upload_path'), url.replace('/assets/uploads', '')); | 
					
						
							|  |  |  | 			const exists = await file.exists(filePath); | 
					
						
							|  |  |  | 			assert(!exists); | 
					
						
							| 
									
										
										
										
											2018-04-06 15:16:28 -04:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		after(emptyUploadsFolder); | 
					
						
							| 
									
										
										
										
											2017-10-31 18:03:54 -04:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 00:01:39 -07:00
										 |  |  | 	describe('admin uploads', () => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 		let jar; | 
					
						
							|  |  |  | 		let csrf_token; | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 		let regularJar; | 
					
						
							|  |  |  | 		let regular_csrf_token; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-22 19:23:51 -05:00
										 |  |  | 		before(async () => { | 
					
						
							| 
									
										
										
										
											2021-11-22 19:26:18 -05:00
										 |  |  | 			({ jar, csrf_token } = await helpers.loginUser('admin', 'barbar')); | 
					
						
							| 
									
										
										
										
											2021-11-22 19:23:51 -05:00
										 |  |  | 			const regularLogin = await helpers.loginUser('regular', 'zugzug'); | 
					
						
							|  |  |  | 			regularJar = regularLogin.jar; | 
					
						
							|  |  |  | 			regular_csrf_token = regularLogin.csrf_token; | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload site logo', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadlogo`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.strictEqual(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert(Array.isArray(body)); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/system/site-logo.png`); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should fail to upload invalid file type', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/503.html'), { params: JSON.stringify({ cid: cid }) }, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.strictEqual(response.statusCode, 500); | 
					
						
							|  |  |  | 			assert.equal(body.error, '[[error:invalid-image-type, image/png&#44; image/jpeg&#44; image/pjpeg&#44; image/jpg&#44; image/gif&#44; image/svg+xml]]'); | 
					
						
							| 
									
										
										
										
											2017-05-10 15:34:36 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should fail to upload category image with invalid json params', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/test.png'), { params: 'invalid json' }, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.strictEqual(response.statusCode, 500); | 
					
						
							|  |  |  | 			assert.equal(body.error, '[[error:invalid-json]]'); | 
					
						
							| 
									
										
										
										
											2017-05-10 15:34:36 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload category image', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/test.png'), { params: JSON.stringify({ cid: cid }) }, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert(Array.isArray(body)); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/category/category-1.png`); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-24 10:34:37 -04:00
										 |  |  | 		it('should upload svg as category image after cleaning it up', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/category/uploadpicture`, path.join(__dirname, '../test/files/dirty.svg'), { params: JSON.stringify({ cid: cid }) }, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert(Array.isArray(body)); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/category/category-1.svg`); | 
					
						
							|  |  |  | 			const svgContents = await fs.readFile(path.join(__dirname, '../test/uploads/category/category-1.svg'), 'utf-8'); | 
					
						
							|  |  |  | 			assert.strictEqual(svgContents.includes('<script>'), false); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload default avatar', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadDefaultAvatar`, path.join(__dirname, '../test/files/test.png'), { }, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/system/avatar-default.png`); | 
					
						
							| 
									
										
										
										
											2017-05-10 16:27:44 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload og image', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadOgImage`, path.join(__dirname, '../test/files/test.png'), { }, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, `${nconf.get('relative_path')}/assets/uploads/system/og-image.png`); | 
					
						
							| 
									
										
										
										
											2017-05-10 16:27:44 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload favicon', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/uploadfavicon`, path.join(__dirname, '../test/files/favicon.ico'), {}, jar, csrf_token); | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert(Array.isArray(body)); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, '/assets/uploads/system/favicon.ico'); | 
					
						
							| 
									
										
										
										
											2016-11-07 14:45:44 +03:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should upload touch icon', async () => { | 
					
						
							| 
									
										
										
										
											2021-02-04 00:06:15 -07:00
										 |  |  | 			const touchiconAssetPath = '/assets/uploads/system/touchicon-orig.png'; | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			const { response, body } = await helpers.uploadFile( | 
					
						
							|  |  |  | 				`${nconf.get('url')}/api/admin/uploadTouchIcon`, | 
					
						
							|  |  |  | 				path.join(__dirname, '../test/files/test.png'), | 
					
						
							|  |  |  | 				{}, | 
					
						
							|  |  |  | 				jar, | 
					
						
							|  |  |  | 				csrf_token | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 200); | 
					
						
							|  |  |  | 			assert(Array.isArray(body)); | 
					
						
							|  |  |  | 			assert.equal(body[0].url, touchiconAssetPath); | 
					
						
							|  |  |  | 			meta.config['brand:touchIcon'] = touchiconAssetPath; | 
					
						
							|  |  |  | 			const { response: res1, body: body1 } = await request.get(`${nconf.get('url')}/apple-touch-icon`); | 
					
						
							|  |  |  | 			assert.equal(res1.statusCode, 200); | 
					
						
							|  |  |  | 			assert(body1); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		it('should upload regular file', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await 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', | 
					
						
							|  |  |  | 				}), | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			}, jar, csrf_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.equal(response.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'))); | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 		it('should fail to upload regular file in wrong directory', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await 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', | 
					
						
							|  |  |  | 				}), | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 			}, jar, csrf_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 500); | 
					
						
							|  |  |  | 			assert.strictEqual(body.error, '[[error:invalid-path]]'); | 
					
						
							| 
									
										
										
										
											2020-06-22 12:08:35 -04:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-10 16:49:40 -04:00
										 |  |  | 		it('should fail to upload regular file if directory does not exist', async () => { | 
					
						
							|  |  |  | 			const { response, body } = await helpers.uploadFile(`${nconf.get('url')}/api/admin/upload/file`, path.join(__dirname, '../test/files/test.png'), { | 
					
						
							|  |  |  | 				params: JSON.stringify({ | 
					
						
							|  |  |  | 					folder: 'does-not-exist', | 
					
						
							|  |  |  | 				}), | 
					
						
							|  |  |  | 			}, jar, csrf_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			assert.equal(response.statusCode, 500); | 
					
						
							|  |  |  | 			assert.strictEqual(body.error, '[[error:invalid-path]]'); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 		describe('ACP uploads screen', () => { | 
					
						
							|  |  |  | 			it('should create a folder', async () => { | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				const { response } = await helpers.createFolder('', 'myfolder', jar, csrf_token); | 
					
						
							|  |  |  | 				assert.strictEqual(response.statusCode, 200); | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 				assert(file.existsSync(path.join(nconf.get('upload_path'), 'myfolder'))); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should fail to create a folder if it already exists', async () => { | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				const { response, body } = await helpers.createFolder('', 'myfolder', jar, csrf_token); | 
					
						
							|  |  |  | 				assert.strictEqual(response.statusCode, 403); | 
					
						
							|  |  |  | 				assert.deepStrictEqual(body.status, { | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 					code: 'forbidden', | 
					
						
							|  |  |  | 					message: 'Folder exists', | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should fail to create a folder as a non-admin', async () => { | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				const { response, body } = await helpers.createFolder('', 'hisfolder', regularJar, regular_csrf_token); | 
					
						
							|  |  |  | 				assert.strictEqual(response.statusCode, 403); | 
					
						
							|  |  |  | 				assert.deepStrictEqual(body.status, { | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 					code: 'forbidden', | 
					
						
							|  |  |  | 					message: 'You are not authorised to make this call', | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should fail to create a folder in wrong directory', async () => { | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				const { response, body } = await helpers.createFolder('../traversing', 'unexpectedfolder', jar, csrf_token); | 
					
						
							|  |  |  | 				assert.strictEqual(response.statusCode, 403); | 
					
						
							|  |  |  | 				assert.deepStrictEqual(body.status, { | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 					code: 'forbidden', | 
					
						
							|  |  |  | 					message: 'Invalid path', | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should use basename of given folderName to create new folder', async () => { | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				const { response } = await helpers.createFolder('/myfolder', '../another folder', jar, csrf_token); | 
					
						
							|  |  |  | 				assert.strictEqual(response.statusCode, 200); | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 				const slugifiedName = 'another-folder'; | 
					
						
							|  |  |  | 				assert(file.existsSync(path.join(nconf.get('upload_path'), 'myfolder', slugifiedName))); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should fail to delete a file as a non-admin', async () => { | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				const { response, body } = await request.delete(`${nconf.get('url')}/api/v3/files`, { | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 					body: { | 
					
						
							|  |  |  | 						path: '/system/test.png', | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 					jar: regularJar, | 
					
						
							|  |  |  | 					headers: { | 
					
						
							|  |  |  | 						'x-csrf-token': regular_csrf_token, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2023-12-18 12:08:34 -05:00
										 |  |  | 				assert.strictEqual(response.statusCode, 403); | 
					
						
							|  |  |  | 				assert.deepStrictEqual(body.status, { | 
					
						
							| 
									
										
										
										
											2021-08-31 16:27:00 +03:00
										 |  |  | 					code: 'forbidden', | 
					
						
							|  |  |  | 					message: 'You are not authorised to make this call', | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		after(emptyUploadsFolder); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	describe('library methods', () => { | 
					
						
							|  |  |  | 		describe('.getOrphans()', () => { | 
					
						
							|  |  |  | 			before(async () => { | 
					
						
							|  |  |  | 				const { jar, csrf_token } = await helpers.loginUser('regular', 'zugzug'); | 
					
						
							| 
									
										
										
										
											2022-08-10 13:24:16 -04:00
										 |  |  | 				await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should return files with no post associated with them', async () => { | 
					
						
							|  |  |  | 				const orphans = await posts.uploads.getOrphans(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-16 05:56:36 +08:00
										 |  |  | 				assert.strictEqual(orphans.length, 1); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 				orphans.forEach((relPath) => { | 
					
						
							| 
									
										
										
										
											2025-04-04 10:45:05 -04:00
										 |  |  | 					assert(relPath.startsWith('/files/')); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 					assert(relPath.endsWith('test.png')); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			after(emptyUploadsFolder); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		describe('.cleanOrphans()', () => { | 
					
						
							|  |  |  | 			let _orphanExpiryDays; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			before(async () => { | 
					
						
							|  |  |  | 				const { jar, csrf_token } = await helpers.loginUser('regular', 'zugzug'); | 
					
						
							| 
									
										
										
										
											2022-08-10 13:24:16 -04:00
										 |  |  | 				await helpers.uploadFile(`${nconf.get('url')}/api/post/upload`, path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// modify all files in uploads folder to be 30 days old
 | 
					
						
							|  |  |  | 				const files = await fs.readdir(`${nconf.get('upload_path')}/files`); | 
					
						
							|  |  |  | 				const p30d = (Date.now() - (1000 * 60 * 60 * 24 * 30)) / 1000; | 
					
						
							|  |  |  | 				await Promise.all(files.map(async (filename) => { | 
					
						
							|  |  |  | 					await fs.utimes(`${nconf.get('upload_path')}/files/${filename}`, p30d, p30d); | 
					
						
							|  |  |  | 				})); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				_orphanExpiryDays = meta.config.orphanExpiryDays; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should not touch orphans if not configured to do so', async () => { | 
					
						
							|  |  |  | 				await posts.uploads.cleanOrphans(); | 
					
						
							|  |  |  | 				const orphans = await posts.uploads.getOrphans(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-16 05:56:36 +08:00
										 |  |  | 				assert.strictEqual(orphans.length, 1); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should not touch orphans if they are newer than the configured expiry', async () => { | 
					
						
							|  |  |  | 				meta.config.orphanExpiryDays = 60; | 
					
						
							|  |  |  | 				await posts.uploads.cleanOrphans(); | 
					
						
							|  |  |  | 				const orphans = await posts.uploads.getOrphans(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-16 05:56:36 +08:00
										 |  |  | 				assert.strictEqual(orphans.length, 1); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:43:11 -04:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			it('should delete orphans older than the configured number of days', async () => { | 
					
						
							|  |  |  | 				meta.config.orphanExpiryDays = 7; | 
					
						
							|  |  |  | 				await posts.uploads.cleanOrphans(); | 
					
						
							|  |  |  | 				const orphans = await posts.uploads.getOrphans(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				assert.strictEqual(orphans.length, 0); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			after(async () => { | 
					
						
							|  |  |  | 				await emptyUploadsFolder(); | 
					
						
							|  |  |  | 				meta.config.orphanExpiryDays = _orphanExpiryDays; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2016-11-01 17:33:19 +03:00
										 |  |  | 	}); | 
					
						
							|  |  |  | }); |