|
|
|
|
@ -32,7 +32,6 @@ import { createUser, deleteUser, login } from '../../data/users.helper'; |
|
|
|
|
import { IS_EE } from '../../e2e/config/constants'; |
|
|
|
|
|
|
|
|
|
const lstURL = './tests/e2e/fixtures/files/lst-test.lst'; |
|
|
|
|
const drawioURL = './tests/e2e/fixtures/files/diagram.drawio'; |
|
|
|
|
const svgLogoURL = './public/images/logo/logo.svg'; |
|
|
|
|
const svgLogoFileName = 'logo.svg'; |
|
|
|
|
|
|
|
|
|
@ -100,320 +99,6 @@ describe('[Rooms]', () => { |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
describe('/rooms.upload', () => { |
|
|
|
|
let testChannel: IRoom; |
|
|
|
|
let user: TestUser<IUser>; |
|
|
|
|
let userCredentials: Credentials; |
|
|
|
|
const testChannelName = `channel.test.upload.${Date.now()}-${Math.random()}`; |
|
|
|
|
let blockedMediaTypes: SettingValue; |
|
|
|
|
let testPrivateChannel: IRoom; |
|
|
|
|
|
|
|
|
|
before(async () => { |
|
|
|
|
user = await createUser({ joinDefaultChannels: false }); |
|
|
|
|
userCredentials = await login(user.username, password); |
|
|
|
|
testChannel = (await createRoom({ type: 'c', name: testChannelName })).body.channel; |
|
|
|
|
testPrivateChannel = (await createRoom({ type: 'p', name: `channel.test.private.${Date.now()}-${Math.random()}` })).body.group; |
|
|
|
|
blockedMediaTypes = await getSettingValueById('FileUpload_MediaTypeBlackList'); |
|
|
|
|
const newBlockedMediaTypes = (blockedMediaTypes as string) |
|
|
|
|
.split(',') |
|
|
|
|
.filter((type) => type !== 'image/svg+xml') |
|
|
|
|
.join(','); |
|
|
|
|
await updateSetting('FileUpload_MediaTypeBlackList', newBlockedMediaTypes); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
after(() => |
|
|
|
|
Promise.all([ |
|
|
|
|
deleteRoom({ type: 'c', roomId: testChannel._id }), |
|
|
|
|
deleteUser(user), |
|
|
|
|
updateSetting('FileUpload_Restrict_to_room_members', true), |
|
|
|
|
updateSetting('FileUpload_Restrict_to_users_who_can_access_room', false), |
|
|
|
|
updateSetting('FileUpload_ProtectFiles', true), |
|
|
|
|
updateSetting('FileUpload_MediaTypeBlackList', blockedMediaTypes), |
|
|
|
|
deleteRoom({ roomId: testPrivateChannel._id, type: 'p' }), |
|
|
|
|
]), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
it("don't upload a file to room with file field other than file", (done) => { |
|
|
|
|
void request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('test', imgURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(400) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', false); |
|
|
|
|
expect(res.body).to.have.property('error', '[invalid-field]'); |
|
|
|
|
expect(res.body).to.have.property('errorType', 'invalid-field'); |
|
|
|
|
}) |
|
|
|
|
.end(done); |
|
|
|
|
}); |
|
|
|
|
it("don't upload a file to room with empty file", (done) => { |
|
|
|
|
void request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', '') |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(400) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', false); |
|
|
|
|
expect(res.body).to.have.property('error', res.body.error); |
|
|
|
|
}) |
|
|
|
|
.end(done); |
|
|
|
|
}); |
|
|
|
|
it("don't upload a file to room with more than 1 file", (done) => { |
|
|
|
|
void request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', imgURL) |
|
|
|
|
.attach('file', imgURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(400) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', false); |
|
|
|
|
expect(res.body).to.have.property('error', 'Just 1 file is allowed'); |
|
|
|
|
}) |
|
|
|
|
.end(done); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
let fileNewUrl: string; |
|
|
|
|
let fileOldUrl: string; |
|
|
|
|
it('should upload a PNG file to room', async () => { |
|
|
|
|
await request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', imgURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200) |
|
|
|
|
.expect((res) => { |
|
|
|
|
const message = res.body.message as IMessage; |
|
|
|
|
expect(res.body).to.have.property('success', true); |
|
|
|
|
expect(res.body).to.have.property('message'); |
|
|
|
|
expect(res.body.message).to.have.property('attachments'); |
|
|
|
|
expect(res.body.message.attachments).to.be.an('array').of.length(1); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('image_type', 'image/png'); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('title', '1024x1024.png'); |
|
|
|
|
expect(res.body.message).to.have.property('files'); |
|
|
|
|
expect(res.body.message.files).to.be.an('array').of.length(2); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('type', 'image/png'); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('name', '1024x1024.png'); |
|
|
|
|
|
|
|
|
|
assert.isDefined(message.file); |
|
|
|
|
fileNewUrl = `/file-upload/${message.file._id}/${message.file.name}`; |
|
|
|
|
fileOldUrl = `/ufs/GridFS:Uploads/${message.file._id}/${message.file.name}`; |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should upload a LST file to room', () => { |
|
|
|
|
return request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', lstURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', true); |
|
|
|
|
expect(res.body).to.have.property('message'); |
|
|
|
|
expect(res.body.message).to.have.property('attachments'); |
|
|
|
|
expect(res.body.message.attachments).to.be.an('array').of.length(1); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('format', 'LST'); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('title', 'lst-test.lst'); |
|
|
|
|
expect(res.body.message).to.have.property('files'); |
|
|
|
|
expect(res.body.message.files).to.be.an('array').of.length(1); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('name', 'lst-test.lst'); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('type', 'text/plain'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should upload a DRAWIO file (unknown media type) to room', () => { |
|
|
|
|
return request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', drawioURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', true); |
|
|
|
|
expect(res.body).to.have.property('message'); |
|
|
|
|
expect(res.body.message).to.have.property('attachments'); |
|
|
|
|
expect(res.body.message.attachments).to.be.an('array').of.length(1); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('format', 'DRAWIO'); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('title', 'diagram.drawio'); |
|
|
|
|
expect(res.body.message).to.have.property('files'); |
|
|
|
|
expect(res.body.message.files).to.be.an('array').of.length(1); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('name', 'diagram.drawio'); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('type', 'application/octet-stream'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not allow uploading a blocked media type to a room', async () => { |
|
|
|
|
await updateSetting('FileUpload_MediaTypeBlackList', 'text/plain'); |
|
|
|
|
await request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', lstURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(400) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', false); |
|
|
|
|
expect(res.body).to.have.property('errorType', 'error-invalid-file-type'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not allow uploading an unknown media type to a room if the default one is blocked', async () => { |
|
|
|
|
await updateSetting('FileUpload_MediaTypeBlackList', 'application/octet-stream'); |
|
|
|
|
await request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', drawioURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(400) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', false); |
|
|
|
|
expect(res.body).to.have.property('errorType', 'error-invalid-file-type'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should be able to get the file', async () => { |
|
|
|
|
await request.get(fileNewUrl).set(credentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
await request.get(fileOldUrl).set(credentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should be able to get the file when no access to the room if setting allows it', async () => { |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_room_members', false); |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_users_who_can_access_room', false); |
|
|
|
|
await request.get(fileNewUrl).set(userCredentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
await request.get(fileOldUrl).set(userCredentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not be able to get the file when no access to the room if setting blocks', async () => { |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_room_members', true); |
|
|
|
|
await request.get(fileNewUrl).set(userCredentials).expect(403); |
|
|
|
|
await request.get(fileOldUrl).set(userCredentials).expect(403); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should be able to get the file if member and setting blocks outside access', async () => { |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_room_members', true); |
|
|
|
|
await request.get(fileNewUrl).set(credentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
await request.get(fileOldUrl).set(credentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should be able to get the file if not member but can access room if setting allows', async () => { |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_room_members', false); |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_users_who_can_access_room', true); |
|
|
|
|
|
|
|
|
|
await request.get(fileNewUrl).set(userCredentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
await request.get(fileOldUrl).set(userCredentials).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not be able to get the file if not member and cannot access room', async () => { |
|
|
|
|
const { body } = await request |
|
|
|
|
.post(api(`rooms.upload/${testPrivateChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', imgURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200); |
|
|
|
|
|
|
|
|
|
const fileUrl = `/file-upload/${body.message.file._id}/${body.message.file.name}`; |
|
|
|
|
|
|
|
|
|
await request.get(fileUrl).set(userCredentials).expect(403); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should respect the setting with less permissions when both are true', async () => { |
|
|
|
|
await updateSetting('FileUpload_ProtectFiles', true); |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_room_members', true); |
|
|
|
|
await updateSetting('FileUpload_Restrict_to_users_who_can_access_room', true); |
|
|
|
|
await request.get(fileNewUrl).set(userCredentials).expect(403); |
|
|
|
|
await request.get(fileOldUrl).set(userCredentials).expect(403); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not be able to get the file without credentials', async () => { |
|
|
|
|
await request.get(fileNewUrl).attach('file', imgURL).expect(403); |
|
|
|
|
await request.get(fileOldUrl).attach('file', imgURL).expect(403); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should be able to get the file without credentials if setting allows', async () => { |
|
|
|
|
await updateSetting('FileUpload_ProtectFiles', false); |
|
|
|
|
await request.get(fileNewUrl).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
await request.get(fileOldUrl).expect('Content-Type', 'image/png').expect(200); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should generate thumbnail for SVG files correctly', async () => { |
|
|
|
|
const expectedFileName = `thumb-${svgLogoFileName}`; |
|
|
|
|
|
|
|
|
|
const res = await request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', svgLogoURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200); |
|
|
|
|
|
|
|
|
|
const message = res.body.message as IMessage; |
|
|
|
|
const { files, attachments } = message; |
|
|
|
|
|
|
|
|
|
expect(files).to.be.an('array'); |
|
|
|
|
const hasThumbFile = files?.some((file) => file.type === 'image/png' && file.name === expectedFileName); |
|
|
|
|
expect(hasThumbFile).to.be.true; |
|
|
|
|
|
|
|
|
|
expect(attachments).to.be.an('array'); |
|
|
|
|
const thumbAttachment = attachments?.find((attachment) => attachment.title === svgLogoFileName); |
|
|
|
|
assert.isDefined(thumbAttachment); |
|
|
|
|
expect(thumbAttachment).to.be.an('object'); |
|
|
|
|
const thumbUrl = (thumbAttachment as ImageAttachmentProps).image_url; |
|
|
|
|
|
|
|
|
|
await request.get(thumbUrl).set(credentials).expect('Content-Type', 'image/png'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should generate thumbnail for JPEG files correctly', async () => { |
|
|
|
|
const expectedFileName = `thumb-sample-jpeg.jpg`; |
|
|
|
|
const res = await request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', fs.createReadStream(path.join(__dirname, '../../mocks/files/sample-jpeg.jpg'))) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200); |
|
|
|
|
|
|
|
|
|
const message = res.body.message as IMessage; |
|
|
|
|
const { files, attachments } = message; |
|
|
|
|
|
|
|
|
|
expect(files).to.be.an('array'); |
|
|
|
|
assert.isDefined(files); |
|
|
|
|
const hasThumbFile = files.some((file) => file.type === 'image/jpeg' && file.name === expectedFileName); |
|
|
|
|
expect(hasThumbFile).to.be.true; |
|
|
|
|
|
|
|
|
|
expect(attachments).to.be.an('array'); |
|
|
|
|
assert.isDefined(attachments); |
|
|
|
|
const thumbAttachment = attachments.find((attachment) => attachment.title === `sample-jpeg.jpg`); |
|
|
|
|
expect(thumbAttachment).to.be.an('object'); |
|
|
|
|
const thumbUrl = (thumbAttachment as ImageAttachmentProps).image_url; |
|
|
|
|
|
|
|
|
|
await request.get(thumbUrl).set(credentials).expect('Content-Type', 'image/jpeg'); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// Support legacy behavior (not encrypting file)
|
|
|
|
|
it('should correctly save file description and properties with type e2e', async () => { |
|
|
|
|
await request |
|
|
|
|
.post(api(`rooms.upload/${testChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.field('description', 'some_file_description') |
|
|
|
|
.attach('file', imgURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', true); |
|
|
|
|
expect(res.body).to.have.property('message'); |
|
|
|
|
expect(res.body.message).to.have.property('attachments'); |
|
|
|
|
expect(res.body.message.attachments).to.be.an('array').of.length(1); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('image_type', 'image/png'); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('title', '1024x1024.png'); |
|
|
|
|
expect(res.body.message).to.have.property('files'); |
|
|
|
|
expect(res.body.message.files).to.be.an('array').of.length(2); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('type', 'image/png'); |
|
|
|
|
expect(res.body.message.files[0]).to.have.property('name', '1024x1024.png'); |
|
|
|
|
expect(res.body.message.attachments[0]).to.have.property('description', 'some_file_description'); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
describe('/rooms.media', () => { |
|
|
|
|
let testChannel: IRoom; |
|
|
|
|
let user: TestUser<IUser>; |
|
|
|
|
@ -1142,7 +827,7 @@ describe('[Rooms]', () => { |
|
|
|
|
}); |
|
|
|
|
it('should successfully delete an image and thumbnail from public channel', (done) => { |
|
|
|
|
void request |
|
|
|
|
.post(api(`rooms.upload/${publicChannel._id}`)) |
|
|
|
|
.post(api(`rooms.media/${publicChannel._id}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', imgURL) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
@ -2962,14 +2647,29 @@ describe('[Rooms]', () => { |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const uploadFile = async ({ roomId, file }: { roomId: IRoom['_id']; file: Buffer | fs.ReadStream | string | boolean | number }) => { |
|
|
|
|
const { body } = await request |
|
|
|
|
.post(api(`rooms.upload/${roomId}`)) |
|
|
|
|
let fileId; |
|
|
|
|
await request |
|
|
|
|
.post(api(`rooms.media/${roomId}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.attach('file', file) |
|
|
|
|
.expect('Content-Type', 'application/json') |
|
|
|
|
.expect(200); |
|
|
|
|
.expect(200) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', true); |
|
|
|
|
expect(res.body).to.have.property('file'); |
|
|
|
|
expect(res.body.file).to.have.property('_id'); |
|
|
|
|
fileId = res.body.file._id; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const res = await request |
|
|
|
|
.post(api(`rooms.mediaConfirm/${roomId}/${fileId}`)) |
|
|
|
|
.set(credentials) |
|
|
|
|
.expect(200) |
|
|
|
|
.expect((res) => { |
|
|
|
|
expect(res.body).to.have.property('success', true); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return body.message.attachments[0]; |
|
|
|
|
return res.body.message.attachments[0]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const getIdFromImgPath = (link: string) => { |
|
|
|
|
|