Skip to content

Commit

Permalink
Merge branch 'develop' into fix/autocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
sampaiodiego committed Jan 23, 2021
2 parents b2c1b9d + 818d707 commit fa570f2
Show file tree
Hide file tree
Showing 93 changed files with 2,844 additions and 654 deletions.
1 change: 1 addition & 0 deletions app/api/server/index.js
Expand Up @@ -38,5 +38,6 @@ import './v1/oauthapps';
import './v1/custom-sounds';
import './v1/custom-user-status';
import './v1/instances';
import './v1/email-inbox';

export { API, APIClass, defaultRateLimiterOptions } from './api';
79 changes: 79 additions & 0 deletions app/api/server/lib/emailInbox.js
@@ -0,0 +1,79 @@
import { EmailInbox } from '../../../models/server/raw';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { Users } from '../../../models';

export async function findEmailInboxes({ userId, query = {}, pagination: { offset, count, sort } }) {
if (!await hasPermissionAsync(userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
const cursor = EmailInbox.find(query, {
sort: sort || { name: 1 },
skip: offset,
limit: count,
});

const total = await cursor.count();

const emailInboxes = await cursor.toArray();

return {
emailInboxes,
count: emailInboxes.length,
offset,
total,
};
}

export async function findOneEmailInbox({ userId, _id }) {
if (!await hasPermissionAsync(userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
return EmailInbox.findOneById(_id);
}

export async function insertOneOrUpdateEmailInbox(userId, emailInboxParams) {
const { _id, active, name, email, description, senderInfo, department, smtp, imap } = emailInboxParams;

if (!_id) {
emailInboxParams._createdAt = new Date();
emailInboxParams._updatedAt = new Date();
emailInboxParams._createdBy = Users.findOne(userId, { fields: { username: 1 } });
return EmailInbox.insertOne(emailInboxParams);
}

const emailInbox = await findOneEmailInbox({ userId, id: _id });

if (!emailInbox) {
throw new Error('error-invalid-email-inbox');
}

const updateEmailInbox = {
$set: {
active,
name,
email,
description,
senderInfo,
smtp,
imap,
_updatedAt: new Date(),
},
};

if (department === 'All') {
updateEmailInbox.$unset = {
department: 1,
};
} else {
updateEmailInbox.$set.department = department;
}

return EmailInbox.updateOne({ _id }, updateEmailInbox);
}

export async function findOneEmailInboxByEmail({ userId, email }) {
if (!await hasPermissionAsync(userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
return EmailInbox.findOne({ email });
}
131 changes: 131 additions & 0 deletions app/api/server/v1/email-inbox.js
@@ -0,0 +1,131 @@
import { check, Match } from 'meteor/check';

import { API } from '../api';
import { findEmailInboxes, findOneEmailInbox, insertOneOrUpdateEmailInbox } from '../lib/emailInbox';
import { hasPermission } from '../../../authorization/server/functions/hasPermission';
import { EmailInbox } from '../../../models';
import Users from '../../../models/server/models/Users';
import { sendTestEmailToInbox } from '../../../../server/features/EmailInbox/EmailInbox_Outgoing';

API.v1.addRoute('email-inbox.list', { authRequired: true }, {
get() {
const { offset, count } = this.getPaginationItems();
const { sort, query } = this.parseJsonQuery();
const emailInboxes = Promise.await(findEmailInboxes({ userId: this.userId, query, pagination: { offset, count, sort } }));

return API.v1.success(emailInboxes);
},
});

API.v1.addRoute('email-inbox', { authRequired: true }, {
post() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
check(this.bodyParams, {
_id: Match.Maybe(String),
name: String,
email: String,
active: Boolean,
description: Match.Maybe(String),
senderInfo: Match.Maybe(String),
department: Match.Maybe(String),
smtp: Match.ObjectIncluding({
password: String,
port: Number,
secure: Boolean,
server: String,
username: String,
}),
imap: Match.ObjectIncluding({
password: String,
port: Number,
secure: Boolean,
server: String,
username: String,
}),
});

const emailInboxParams = this.bodyParams;

const { _id } = emailInboxParams;

Promise.await(insertOneOrUpdateEmailInbox(this.userId, emailInboxParams));

return API.v1.success({ _id });
},
});

API.v1.addRoute('email-inbox/:_id', { authRequired: true }, {
get() {
check(this.urlParams, {
_id: String,
});

const { _id } = this.urlParams;
if (!_id) { throw new Error('error-invalid-param'); }
const emailInboxes = Promise.await(findOneEmailInbox({ userId: this.userId, _id }));

return API.v1.success(emailInboxes);
},
delete() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
check(this.urlParams, {
_id: String,
});

const { _id } = this.urlParams;
if (!_id) { throw new Error('error-invalid-param'); }

const emailInboxes = EmailInbox.findOneById(_id);

if (!emailInboxes) {
return API.v1.notFound();
}
EmailInbox.removeById(_id);
return API.v1.success({ _id });
},
});

API.v1.addRoute('email-inbox.search', { authRequired: true }, {
get() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
check(this.queryParams, {
email: String,
});

const { email } = this.queryParams;
const emailInbox = Promise.await(EmailInbox.findOne({ email }));

return API.v1.success({ emailInbox });
},
});

API.v1.addRoute('email-inbox.send-test/:_id', { authRequired: true }, {
post() {
if (!hasPermission(this.userId, 'manage-email-inbox')) {
throw new Error('error-not-allowed');
}
check(this.urlParams, {
_id: String,
});

const { _id } = this.urlParams;
if (!_id) { throw new Error('error-invalid-param'); }
const emailInbox = Promise.await(findOneEmailInbox({ userId: this.userId, _id }));

if (!emailInbox) {
return API.v1.notFound();
}

const user = Users.findOneById(this.userId);

Promise.await(sendTestEmailToInbox(emailInbox, user));

return API.v1.success({ _id });
},
});
7 changes: 6 additions & 1 deletion app/api/server/v1/rooms.js
Expand Up @@ -234,7 +234,7 @@ API.v1.addRoute('rooms.leave', { authRequired: true }, {

API.v1.addRoute('rooms.createDiscussion', { authRequired: true }, {
post() {
const { prid, pmid, reply, t_name, users } = this.bodyParams;
const { prid, pmid, reply, t_name, users, encrypted } = this.bodyParams;
if (!prid) {
return API.v1.failure('Body parameter "prid" is required.');
}
Expand All @@ -245,12 +245,17 @@ API.v1.addRoute('rooms.createDiscussion', { authRequired: true }, {
return API.v1.failure('Body parameter "users" must be an array.');
}

if (encrypted !== undefined && typeof encrypted !== 'boolean') {
return API.v1.failure('Body parameter "encrypted" must be a boolean when included.');
}

const discussion = Meteor.runAsUser(this.userId, () => Meteor.call('createDiscussion', {
prid,
pmid,
t_name,
reply,
users: users || [],
encrypted,
}));

return API.v1.success({ discussion });
Expand Down
9 changes: 6 additions & 3 deletions app/apps/client/orchestrator.js
Expand Up @@ -65,11 +65,12 @@ class AppClientOrchestrator {

getAppsFromMarketplace = async () => {
const appsOverviews = await APIClient.get('apps', { marketplace: 'true' });
return appsOverviews.map(({ latest, price, pricingPlans, purchaseType }) => ({
return appsOverviews.map(({ latest, price, pricingPlans, purchaseType, permissions }) => ({
...latest,
price,
pricingPlans,
purchaseType,
permissions,
}));
}

Expand Down Expand Up @@ -125,20 +126,22 @@ class AppClientOrchestrator {
return languages;
}

installApp = async (appId, version) => {
installApp = async (appId, version, permissionsGranted) => {
const { app } = await APIClient.post('apps/', {
appId,
marketplace: true,
version,
permissionsGranted,
});
return app;
}

updateApp = async (appId, version) => {
updateApp = async (appId, version, permissionsGranted) => {
const { app } = await APIClient.post(`apps/${ appId }`, {
appId,
marketplace: true,
version,
permissionsGranted,
});
return app;
}
Expand Down
5 changes: 1 addition & 4 deletions app/apps/server/bridges/listeners.js
Expand Up @@ -41,10 +41,7 @@ export class AppListenerBridge {
case AppInterface.IPostLivechatGuestSaved:
case AppInterface.IPostLivechatRoomSaved:
return 'livechatEvent';
case AppInterface.IUIKitInteractionHandler:
case AppInterface.IUIKitLivechatInteractionHandler:
case AppInterface.IPostExternalComponentOpened:
case AppInterface.IPostExternalComponentClosed:
default:
return 'defaultEvent';
}
})();
Expand Down

0 comments on commit fa570f2

Please sign in to comment.