Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions app/lib/server/functions/notifications/serviceAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { metrics } from '../../../../metrics';
import { Notifications } from '../../../../notifications';

export function shouldNotifyServiceAccountOwner({
hasMentionToAll,
hasMentionToHere,
isHighlighted,
hasMentionToUser,
hasReplyToThread,
roomType,
}) {
return roomType === 'd' || hasMentionToAll || hasMentionToHere || isHighlighted || hasMentionToUser || hasReplyToThread;
}

export function notifyServiceAccountOwner(receiver, ownerId, message, room) {
metrics.notificationsSent.inc({ notification_type: 'sa' });
Notifications.notifyUser(ownerId, 'sa-notification', {
payload: {
_id: message._id,
rid: message.rid,
sender: message.u,
receiver: receiver.username,
type: room.t,
name: room.name,
},
});
}
14 changes: 14 additions & 0 deletions app/lib/server/lib/sendNotificationsOnMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { sendEmail, shouldNotifyEmail } from '../functions/notifications/email';
import { sendSinglePush, shouldNotifyMobile } from '../functions/notifications/mobile';
import { notifyDesktopUser, shouldNotifyDesktop } from '../functions/notifications/desktop';
import { notifyAudioUser, shouldNotifyAudio } from '../functions/notifications/audio';
import { notifyServiceAccountOwner, shouldNotifyServiceAccountOwner } from '../functions/notifications/serviceAccount';

export const sendNotification = async ({
subscription,
Expand Down Expand Up @@ -46,6 +47,7 @@ export const sendNotification = async ({
status: 1,
statusConnection: 1,
username: 1,
u: 1,
},
}),
];
Expand Down Expand Up @@ -149,6 +151,17 @@ export const sendNotification = async ({
return false;
});
}

if (receiver.u && shouldNotifyServiceAccountOwner({
hasMentionToAll,
hasMentionToHere,
isHighlighted,
hasMentionToUser,
hasReplyToThread,
roomType,
})) {
notifyServiceAccountOwner(receiver, receiver.u._id, message, room);
}
};

const project = {
Expand All @@ -168,6 +181,7 @@ const project = {
'receiver.status': 1,
'receiver.statusConnection': 1,
'receiver.username': 1,
'receiver.u': 1,
},
};

Expand Down
65 changes: 65 additions & 0 deletions app/service-accounts/client/stylesheets/serviceAccounts.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
.rc-service-account-list {
&__user {

display: flex;

padding: 8px 0;

cursor: pointer;
align-items: center;

&.active,
&:hover {
background-color: #eeeeee;

& .rc-member-list__menu {
opacity: 1;
}
}

& > .avatar {
width: var(--sidebar-account-thumb-size);
height: var(--sidebar-account-thumb-size);
}
}

&__username {
display: flex;
flex: 1 1 auto;

margin: 0 12px 0 8px;

font-size: 16px;
align-items: center;
}

&__username-alert {
font-weight: bold;
}

&__add {
display: inline-block;

width: 100%;

padding: 4px 0;

cursor: pointer;

user-select: none;

transition: all 0.3s;

text-align: center;

color: var(--popover-item-color);

font-size: var(--popover-item-text-size);

align-items: center;
}
}

.service-account-notification {
color: var(--rc-color-alert-message-primary-background);
}
51 changes: 33 additions & 18 deletions app/service-accounts/client/views/serviceAccountSidebarLogin.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
<template name="serviceAccountSidebarLogin">
<div class="rc-popover__column">
<ul class="rc-popover__list">
{{#if showOwnerAccountLink}}
<p>Go back to main account</p>
<li class='rc-member-list__user js-login'>
{{> avatar username=owner.username}}
<div class="rc-member-list__username">
{{owner.username}}
</div>
</li>
{{#if loading}}
<p>Loading ... </p>
{{else}}
{{#if hasServiceAccounts}}
{{#each users}}
<li class='rc-member-list__user js-login'>
{{> avatar username=username}}
<div class="rc-member-list__username">
{{username}}
</div>
</li>
{{/each}}
{{#if showOwnerAccountLink}}
<p>Go back to main account</p>
<li class='rc-service-account-list__user js-login'>
{{> avatar username=owner.username}}
<div class="rc-service-account-list__username">
{{owner.username}}
</div>
</li>
{{else}}
<p>{{_ "You_have_no_service_accounts"}}</p>
{{#if hasServiceAccounts}}
{{#each users}}
<li class='rc-service-account-list__user js-login'>
{{> avatar username=username}}
<div class="rc-service-account-list__username">
{{#if receivedNewMessage username}}
<span class="rc-service-account-list__username-alert">
{{username}}
</span>
{{else}}
{{username}}
{{/if}}
</div>
<div class="badge">
{{unread}}
</div>
</li>
{{/each}}
{{else}}
<p>{{_ "You_have_no_service_accounts"}}</p>
{{/if}}
{{/if}}
<hr>
<span class='rc-service-account-list__add js-add'>{{_ "Add_service_account"}}</span>
{{/if}}
</ul>
</div>
Expand Down
64 changes: 46 additions & 18 deletions app/service-accounts/client/views/serviceAccountSidebarLogin.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import { Meteor } from 'meteor/meteor';
import { ReactiveVar } from 'meteor/reactive-var';
import { Template } from 'meteor/templating';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Session } from 'meteor/session';

import { handleError } from '../../../utils';
import { handleError, t } from '../../../utils';
import { callbacks } from '../../../callbacks';
import FullUser from '../../../models/client/models/FullUser';
import './serviceAccountSidebarLogin.html';
import { popover } from '../../../ui-utils/client';
import { popover, modal } from '../../../ui-utils';

Template.serviceAccountSidebarLogin.helpers({
isReady() {
const instance = Template.instance();
return instance.ready && instance.ready.get();
loading() {
return Template.instance().loading.get();
},
users() {
return Template.instance().users();
return Template.instance().users.get();
},
hasServiceAccounts() {
return Template.instance().users() && Template.instance().users().length > 0;
return Template.instance().users.get() && Template.instance().users.get().length > 0;
},
owner() {
return Meteor.user() && Meteor.user().u;
},
showOwnerAccountLink() {
return localStorage.getItem('serviceAccountForceLogin') && Meteor.user() && !!Meteor.user().u;
},
receivedNewMessage(username) {
if (Template.instance().notifiedServiceAccount) {
return username === Template.instance().notifiedServiceAccount.get();
}
return false;
},
});

Template.serviceAccountSidebarLogin.events({
Expand Down Expand Up @@ -57,21 +63,43 @@ Template.serviceAccountSidebarLogin.events({
});
});
},
'click .js-add'(e) {
e.preventDefault();
popover.close();
modal.open({
title: t('Service_account_title'),
content: 'createServiceAccount',
data: {
onCreate() {
modal.close();
},
},
modifier: 'modal',
showConfirmButton: false,
showCancelButton: false,
confirmOnEnter: false,
});
},
});

Template.serviceAccountSidebarLogin.onCreated(function() {
const instance = this;
this.ready = new ReactiveVar(true);
this.users = new ReactiveVar([]);
this.loading = new ReactiveVar(true);
this.notifiedServiceAccount = new ReactiveVar('');
instance.notifiedServiceAccount.set(Session.get('saMessageReceiver'));
Session.delete('saMessageReceiver');
Session.delete('saNotification');
this.autorun(() => {
const subscription = instance.subscribe('userServiceAccounts');
instance.ready.set(subscription.ready());
instance.loading.set(true);
Meteor.call('getLinkedServiceAccounts', function(err, serviceAccounts) {
if (err) {
this.loading.set(false);
return handleError(err);
}
instance.users.set(serviceAccounts);
instance.loading.set(false);
});
});
this.users = function() {
const query = {
'u._id': Meteor.userId(),
active: true,
};
const limit = instance.limit && instance.limit.get();
return FullUser.find(query, { limit, sort: { username: 1, name: 1 } }).fetch();
};
});
2 changes: 1 addition & 1 deletion app/service-accounts/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import './api/rest';
import './methods/usernameExists';
import './methods/addServiceAccount';
import './methods/getLoginToken';
import './methods/getLinkedServiceAccounts';

import './hooks/serviceAccountCallback';
import './hooks/serviceAccountBroadcast';

import './publications/fullServiceAccountData';
import './publications/userServiceAccounts';

import '../lib/serviceAccountRoomType';
22 changes: 22 additions & 0 deletions app/service-accounts/server/methods/getLinkedServiceAccounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Meteor } from 'meteor/meteor';

import { Users, Subscriptions } from '../../../models';
import { getDefaultUserFields } from '../../../utils/server/functions/getDefaultUserFields';

Meteor.methods({
getLinkedServiceAccounts() {
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'addServiceAccount' });
}

const query = {
'u._id': Meteor.userId(),
active: true,
};
const result = Users.find(query, { fields: getDefaultUserFields() }).fetch();
result.forEach((serviceAccount) => {
serviceAccount.unread = Subscriptions.findUnreadByUserId(serviceAccount._id).count();
});
return result;
},
});
25 changes: 0 additions & 25 deletions app/service-accounts/server/publications/userServiceAccounts.js

This file was deleted.

10 changes: 8 additions & 2 deletions app/ui-sidenav/client/sidebarHeader.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
</div>
<div class="sidebar__toolbar">
{{#each toolbarButtons}}
<button class="sidebar__toolbar-button rc-tooltip rc-tooltip--down js-button" aria-label="{{name}}">
{{> icon block="sidebar__toolbar-button-icon" icon=icon }}
<button class=" sidebar__toolbar-button rc-tooltip rc-tooltip--down js-button" aria-label="{{name}}">
{{#if active}}
<span class="service-account-notification">
{{> icon block="sidebar__toolbar-button-icon" icon=icon }}
</span>
{{else}}
{{> icon block="sidebar__toolbar-button-icon" icon=icon }}
{{/if}}
</button>
{{/each}}
</div>
Expand Down
Loading