license manager

This commit is contained in:
Serghey Rodin 2015-11-02 15:28:16 +02:00
parent 45fd7dc75b
commit 60ebfe321a
13 changed files with 534 additions and 47 deletions

62
bin/v-activate-vesta-license Executable file
View file

@ -0,0 +1,62 @@
#!/bin/bash
# info: activate vesta license
# options: MODULE LICENSE
#
# The function activates and register vesta license
#----------------------------------------------------------#
# Variable&Function #
#----------------------------------------------------------#
# Argument defenition
module=$(echo $1 | tr '[:lower:]' '[:upper:]')
license=$2
# Importing system enviroment
source /etc/profile
# Includes
source $VESTA/func/main.sh
source $VESTA/conf/vesta.conf
#----------------------------------------------------------#
# Verifications #
#----------------------------------------------------------#
# Checking arg number
check_args '2' "$#" 'MODULE LICENSE'
#----------------------------------------------------------#
# Action #
#----------------------------------------------------------#
# Activating license
v_host='https://vestacp.com/checkout'
answer=$(curl -s $v_host/activate.php?licence_key=$license&module=$module)
check_result $? "cant' connect to vestacp.com " $E_CONNECT
# Checking server answer
if [[ "$answer" != '0' ]]; then
echo "Error: $module license $license is invalid"
exit $E_INVALID
fi
#----------------------------------------------------------#
# Vesta #
#----------------------------------------------------------#
# Updating vesta.conf
if [ -z "$(grep "${module}_KEY" $VESTA/conf/vesta.conf)" ]; then
echo "${module}_KEY='$license'" >> $VESTA/conf/vesta.conf
else
sed -i "s/${module}_KEY=.*/${module}_KEY='$license'/g" $VESTA/conf/vesta.conf
fi
# Logging
log_event "$OK" "$EVENT"
exit

59
bin/v-check-vesta-license Executable file
View file

@ -0,0 +1,59 @@
#!/bin/bash
# info: check vesta license
# options: [MODULE]
#
# The function activates and register vesta license
#----------------------------------------------------------#
# Variable&Function #
#----------------------------------------------------------#
# Argument defenition
module=$(echo $1 | tr '[:lower:]' '[:upper:]')
# Importing system enviroment
source /etc/profile
# Includes
source $VESTA/func/main.sh
source $VESTA/conf/vesta.conf
#----------------------------------------------------------#
# Verifications #
#----------------------------------------------------------#
#----------------------------------------------------------#
# Action #
#----------------------------------------------------------#
# Checking module
if [ -z "$module" ]; then
modules=$(grep _KEY= $VESTA/conf/vesta.conf)
else
modules=$(grep "${module}_KEY" $VESTA/conf/vesta.conf)
fi
IFS=$'\n'
for str in $modules; do
module=$(echo "$str" |cut -f 1 -d _)
license=$(echo "$str" |cut -f 2 -d \')
if [ ! -z "$license" ]; then
v_host='https://vestacp.com/checkout'
answer=$(curl -s $v_host/check.php?licence_key=$license)
check_result $? "cant' connect to vestacp.com " 0
if [[ "$answer" != '0' ]]; then
sed -i "s/${module}_KEY=.*/${module}_KEY=''/g" $VESTA/conf/vesta.conf
echo "deactivating $module"
fi
fi
done
#----------------------------------------------------------#
# Vesta #
#----------------------------------------------------------#
exit

61
bin/v-deactivate-vesta-license Executable file
View file

@ -0,0 +1,61 @@
#!/bin/bash
# info: deactivate vesta license
# options: MODULE LICENSE
#
# The function activates and register vesta license
#----------------------------------------------------------#
# Variable&Function #
#----------------------------------------------------------#
# Argument defenition
module=$(echo $1 | tr '[:lower:]' '[:upper:]')
license=$2
# Importing system enviroment
source /etc/profile
# Includes
source $VESTA/func/main.sh
source $VESTA/conf/vesta.conf
#----------------------------------------------------------#
# Verifications #
#----------------------------------------------------------#
# Checking arg number
check_args '2' "$#" 'MODULE LICENSE'
#----------------------------------------------------------#
# Action #
#----------------------------------------------------------#
# Activating license
v_host='https://vestacp.com/checkout'
answer=$(curl -s $v_host/cancel.php?licence_key=$license)
check_result $? "cant' connect to vestacp.com " $E_CONNECT
echo $answer
# Checking server answer
if [[ "$answer" != '0' ]]; then
echo "Error: $module license $license is invalid"
exit $E_INVALID
fi
#----------------------------------------------------------#
# Vesta #
#----------------------------------------------------------#
# Updating vesta.conf
if [ ! -z "$(grep "${module}_KEY" $VESTA/conf/vesta.conf)" ]; then
sed -i "s/${module}_KEY=.*/${module}_KEY=''/g" $VESTA/conf/vesta.conf
fi
# Logging
log_event "$OK" "$EVENT"
exit

View file

@ -799,11 +799,6 @@ input[type="checkbox"] {
background-color: #c4da5e; background-color: #c4da5e;
} }
.l-profile__notifications.updates { .l-profile__notifications.updates {
background-position: -165px -135px;
}
.l-profile__notifications.updates2 {
/* background-position: -202px -135px; */
background-position: -202px -157px; background-position: -202px -157px;
} }
@ -820,32 +815,40 @@ input[type="checkbox"] {
z-index: 21; z-index: 21;
font-size: 12px; font-size: 12px;
padding: 0; padding: 0;
color: #9E9E9E; color: #7f7f7f;
} }
.notification-container .unseen {
color: #ABABAB;
}
.notification-container li { .notification-container li {
border-bottom: 1px solid #555; border-bottom: 1px solid #555;
padding: 10px 15px 24px; padding: 10px 15px 24px;
} }
.notification-container .mark-seen { .notification-container .mark-seen {
background: rgba(0, 0, 0, 0) url("/images/sprite.png") repeat scroll -427px -486px; background-color: #abc04b;
border: 5px solid #454545; border: 2px solid #454545;
border-radius: 12px; border-radius: 10px;
cursor: pointer; cursor: pointer;
display: inline-block; display: none;
float: right; float: right;
height: 9px; height: 7px;
margin-right: -8px; margin-right: -5px;
margin-top: -3px; margin-top: 0;
width: 9px; width: 7px;
} }
.notification-container .mark-seen:hover { .notification-container .mark-seen:hover {
background-color: #333; background-color: #333;
border-color: #333; border-color: #abc04b;
} }
.notification-container .mark-seen:active { .notification-container .mark-seen:active {
background-color: #777; background-color: #777;
border-color: #777; border-color: #777;
} }
.notification-container .unseen .mark-seen{
display: inline-block;
}
.notification-container .title { .notification-container .title {
color: #9e9e9e; color: #9e9e9e;
font-weight: bold; font-weight: bold;
@ -870,7 +873,6 @@ input[type="checkbox"] {
color: #dacf2e; color: #dacf2e;
} }
.notification-container a { .notification-container a {
color: #5ABDB5;/* #eee;*/ color: #5ABDB5;/* #eee;*/
} }
@ -881,6 +883,21 @@ input[type="checkbox"] {
color: #00C0C0; color: #00C0C0;
} }
.notification-container .icon {
display: inline-block;
width: 0;
}
.notification-container .icon.filemanager {
display: inline-block;
width: 22px;
background: url("/images/flat_icons.png") repeat scroll -31px -100px;
}
.notification-container .icon.starred {
display: inline-block;
width: 21px;
background: url("/images/sprite.png") repeat scroll -184px 556px;
}
.l-stat { .l-stat {
@ -3001,6 +3018,10 @@ form#vstobjects.suspended {
background-color: #5f9491; background-color: #5f9491;
} }
.description.cancel-success {
color: #8fac0a;
font-weight: bold;
}
.description .licence { .description .licence {
padding: 20px 0; padding: 20px 0;

View file

@ -0,0 +1,30 @@
<?php
// Init
error_reporting(NULL);
session_start();
include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
// Check token
if ((!isset($_GET['token'])) || ($_SESSION['token'] != $_GET['token'])) {
header('location: /login/');
exit();
}
if($_GET['delete'] == 1){
$v_username = escapeshellarg($user);
$v_id = escapeshellarg((int)$_GET['notification_id']);
exec (VESTA_CMD."v-delete-user-notification ".$v_username." ".$v_id, $output, $return_var);
check_return_code($return_var,$output);
unset($output);
} else {
$v_username = escapeshellarg($user);
$v_id = escapeshellarg((int)$_GET['notification_id']);
echo VESTA_CMD."v-acknowledge-user-notification ".$v_username." ".$v_id;
exec (VESTA_CMD."v-acknowledge-user-notification ".$v_username." ".$v_id, $output, $return_var);
check_return_code($return_var,$output);
unset($output);
}
exit;

View file

@ -1,7 +1,7 @@
<?php <?php
// Init // Init
error_reporting(NULL); //error_reporting(NULL);
ob_start(); //ob_start();
session_start(); session_start();
$TAB = 'SERVER'; $TAB = 'SERVER';
@ -333,6 +333,67 @@ if (!empty($_POST['save'])) {
if (empty($_SESSION['error_msg'])) { if (empty($_SESSION['error_msg'])) {
$_SESSION['ok_msg'] = __('Changes has been saved.'); $_SESSION['ok_msg'] = __('Changes has been saved.');
} }
// activating sftp licence
if (empty($_SESSION['error_msg'])) {
if($_SESSION['SFTP_KEY'] != $_POST['v_sftp_licence'] && $_POST['v_sftp'] == 'yes'){
$module = 'sftpjail';
$licence_key = escapeshellarg($_POST['v_sftp_licence']);
exec (VESTA_CMD."v-activate-vesta-license ".$module." ".$licence_key, $output, $return_var);
check_return_code($return_var,$output);
unset($output);
if (empty($_SESSION['error_msg'])) {
$_SESSION['ok_msg'] = __('Licence Activated');
$_SESSION['SFTP_KEY'] = $_POST['v_sftp_licence'];
}
}
}
// cancel sftp licence
if (empty($_SESSION['error_msg'])) {
if($_POST['v_sftp'] == 'cancel' && $_SESSION['SFTP_KEY']){
$module = 'sftpjail';
$licence_key = escapeshellarg($_SESSION['SFTP_KEY']);
exec (VESTA_CMD."v-deactivate-vesta-license ".$module." ".$licence_key, $output, $return_var);
check_return_code($return_var,$output);
unset($output);
if (empty($_SESSION['error_msg'])) {
$_SESSION['ok_msg'] = __('Licence Deactivated');
unset($_SESSION['SFTP_KEY']);
}
}
}
// activating filemanager licence
if (empty($_SESSION['error_msg'])) {
if($_SESSION['FILEMANAGER_KEY'] != $_POST['v_filemanager_licence'] && $_POST['v_filemanager'] == 'yes'){
$module = 'filemanager';
$licence_key = escapeshellarg($_POST['v_filemanager_licence']);
exec (VESTA_CMD."v-activate-vesta-license ".$module." ".$licence_key, $output, $return_var);
check_return_code($return_var,$output);
unset($output);
if (empty($_SESSION['error_msg'])) {
$_SESSION['ok_msg'] = __('Licence Activated');
$_SESSION['FILEMANAGER_KEY'] = $_POST['v_filemanager_licence'];
}
}
}
// cancel filemanager licence
if (empty($_SESSION['error_msg'])) {
if($_POST['v_filemanager'] == 'cancel' && $_SESSION['FILEMANAGER_KEY']){
$module = 'filemanager';
$licence_key = escapeshellarg($_SESSION['FILEMANAGER_KEY']);
exec (VESTA_CMD."v-deactivate-vesta-license ".$module." ".$licence_key, $output, $return_var);
check_return_code($return_var,$output);
unset($output);
if (empty($_SESSION['error_msg'])) {
$_SESSION['ok_msg'] = __('Licence Deactivated');
unset($_SESSION['FILEMANAGER_KEY']);
}
}
}
} }
// Check system configuration // Check system configuration

View file

@ -867,7 +867,7 @@ App.Ajax.request = function(method, data, callback, onError){
callback && callback(reply); callback && callback(reply);
} }
catch(e) { catch(e) {
alert('GENERAL ERROR: '+e); fb.error('GENERAL ERROR with ajax method: ' + data.request_method + ' ' + e);
//App.Helpers.generalError(); //App.Helpers.generalError();
} }
} }

View file

@ -8,6 +8,7 @@ var VE = { // Vesta Events object
menu_active_selector: '.l-stat__col--active' menu_active_selector: '.l-stat__col--active'
} }
}, // menu and element navigation functions }, // menu and element navigation functions
notifications: {},
callbacks: { // events callback functions callbacks: { // events callback functions
click: {}, click: {},
mouseover: {}, mouseover: {},
@ -353,6 +354,57 @@ VE.navigation.switch_menu = function(position){
} }
} }
VE.notifications.get_list = function(){
/// TODO get notifications only once
$.ajax({
url: "/list/notifications/?ajax=1",
dataType: "json"
}).done(function(data) {
var acc = [];
$.each(data, function(i, elm){
var tpl = Tpl.get('notification', 'WEB');
if(elm.ACK == 'no')
tpl.set(':UNSEEN', 'unseen');
else
tpl.set(':UNSEEN', '');
tpl.set(':ID', elm.ID);
tpl.set(':TYPE', elm.TYPE);
tpl.set(':TOPIC', elm.TOPIC);
tpl.set(':NOTICE', elm.NOTICE);
acc.push(tpl.finalize());
});
$('.notification-container').html(acc.done()).show();
$('.notification-container .mark-seen').click(function(event){
/// TODO add token
VE.notifications.mark_seen($(event.target).attr('id').replace("notification-", ""));
// VE.notifications.delete($(event.target).attr('id').replace("notification-", ""));
});
});
}
VE.notifications.delete = function(id){
$('#notification-'+id).parents('li').remove();
$.ajax({
url: "/delete/notification/?delete=1&notification_id="+id+"&token="+$('#token').attr('token')
});
}
VE.notifications.mark_seen = function(id){
$('#notification-'+id).parents('li').removeClass('unseen');
$.ajax({
url: "/delete/notification/?notification_id="+id+"&token="+$('#token').attr('token')
});
if($('.notification-container .unseen').length == 0)
$('.l-profile__notifications').removeClass('updates');
}
VE.navigation.init = function(){ VE.navigation.init = function(){

View file

@ -4,7 +4,14 @@
*/ */
App.Templates.html = { App.Templates.html = {
WEB: { WEB: {
hint: [''] hint: [''],
notification: [
'<li class="~!:UNSEEN~!"><span class="mark-seen" id="notification-~!:ID~!">&nbsp;</span>\
<span class="title"><span class="icon ~!:TYPE~!">&nbsp;</span>~!:TOPIC~!</span>\
~!:NOTICE~!\
</li>'
]
}, },
// file manager // file manager
// //

View file

@ -0,0 +1,45 @@
<?php
session_start();
error_reporting(NULL);
// Main include
include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
if($_REQUEST['ajax'] == 1){
// Data
exec (VESTA_CMD."v-list-user-notifications $user json", $output, $return_var);
$data = json_decode(implode('', $output), true);
$data = array_reverse($data,true);
foreach($data as $key => $note){
$note['ID'] = $key;
$data[$key] = $note;
}
echo json_encode($data);
exit();
}
$TAB = 'NOTIFICATIONS';
// Header
include($_SERVER['DOCUMENT_ROOT'].'/templates/header.html');
// Panel
top_panel($user,$TAB);
// Data
exec (VESTA_CMD."v-list-user-notifications $user json", $output, $return_var);
$data = json_decode(implode('', $output), true);
$data = array_reverse($data,true);
if ($_SESSION['user'] == 'admin') {
include($_SERVER['DOCUMENT_ROOT'].'/templates/admin/list_notifications.html');
} else {
include($_SERVER['DOCUMENT_ROOT'].'/templates/user/list_notifications.html');
}
// Back uri
$_SESSION['back'] = $_SERVER['REQUEST_URI'];
// Footer
include($_SERVER['DOCUMENT_ROOT'].'/templates/footer.html');

View file

@ -1,4 +1,5 @@
<?php <?php
error_reporting(NULL);
session_start(); session_start();
$TAB = 'USER'; $TAB = 'USER';

View file

@ -605,13 +605,13 @@
<tr> <tr>
<td class="vst-text input-label step-top"> <td class="vst-text input-label step-top">
<a href="javascript:elementHideShow('vesta');" class="vst-text"> <a href="javascript:elementHideShow('vesta');" class="vst-text">
<b><?php print __('Vesta Control Panel Plugins');?> <span style="color:#ff6701;font-size:10px; padding:0 10px;">preview</span><img src="/images/arrow.png"></b> <b><?php print __('Vesta Control Panel Plugins');?> <!-- span style="color:#ff6701;font-size:10px; padding:0 10px;">preview</span--><img src="/images/arrow.png"></b>
</a> </a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="vst-text input-label step-left"> <td class="vst-text input-label step-left">
<table style="display:<?php if (empty($v_adv)) echo 'none';?> ;" id="vesta"> <table style="display:<?php if (empty($v_adv) && $_GET['lead'] != 'filemanager' && $_GET['lead'] != 'sftp') echo 'none';?> ;" id="vesta">
<tr> <tr>
<td class="vst-text"> <td class="vst-text">
<?php print __('Version') ?> <?php print __('Version') ?>
@ -630,7 +630,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<select class="vst-list" name="v_reseller"> <select class="vst-list" name="v_reseller" disabled="disabled">
<option value='no'><?php print __('no'); ?></option> <option value='no'><?php print __('no'); ?></option>
</select> </select>
<br><br> <br><br>
@ -643,7 +643,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<select class="vst-list" name="v_conf_editor"> <select class="vst-list" name="v_conf_editor" disabled="disabled">
<option value='no'><?php print __('no'); ?></option> <option value='no'><?php print __('no'); ?></option>
</select> </select>
<br><br> <br><br>
@ -656,7 +656,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<select class="vst-list" name="v_template_manager"> <select class="vst-list" name="v_template_manager" disabled="disabled">
<option value='no'><?php print __('no'); ?></option> <option value='no'><?php print __('no'); ?></option>
</select> </select>
<br><br> <br><br>
@ -669,35 +669,111 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<select class="vst-list" name="v_backup_manager"> <select class="vst-list" name="v_backup_manager" disabled="disabled">
<option value='no'><?php print __('no'); ?></option> <option value='no'><?php print __('no'); ?></option>
</select> </select>
<br><br> <br><br>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="vst-text"> <td class="vst-text" id="module-sftp">
<?php print __('FileManager') ?> <?php print __('SFTP Chroot') ?>
</td>
</tr>
<tr>
<td>
<select class="vst-list" name="v_sftp">
<?
if($_SESSION['SFTP_KEY']){
echo '<option value="cancel">'.__('Disable and Cancel Licence').'</option>';
} else {
echo '<option value="no">'.__('no').'</option>';
}
?>
<option value='yes' <? if($_GET['lead'] == 'sftp' || $_SESSION['SFTP_KEY'] != '') echo 'selected="selected"'; ?>><?php print __('yes'); ?></option>
</select>
<br><br>
<div class="sftp description" <? if($_GET['lead'] != 'sftp' && !$_SESSION['SFTP_KEY']) echo 'style="display:none"'; ?>>
<?
if($_GET['sftp_licence_key'] != '' || $_SESSION['SFTP_KEY']){
$licence_key = $_GET['sftp_licence_key'] != '' ? $_GET['sftp_licence_key'] : $_SESSION['SFTP_KEY'];
echo 'Restrict users so that they cannot use SSH and access only their home directory.
<div class="licence">
Licence Key: <input type="text" class="vst-input" name="v_sftp_licence" value="'.$licence_key.'" /><br>
</div>';
} else {
echo '
Restrict users so that they cannot use SSH and access only their home directory.
This is a commercial module, you would need to purchace license key to enable it.
<div class="licence">
Enter License Key: <input type="text" class="vst-input" name="v_sftp_licence" /><br>
</div>
<ul>
<li>
<a href="https://vestacp.com/checkout/2co.php?demo=Y&product_id=6&referer='.$_SERVER['HTTP_HOST'].'" class="purchase">Buy Licence 1$/month</a>
</li>
<li>
<a href="https://vestacp.com/checkout/2co.php?demo=Y&product_id=9&referer='.$_SERVER['HTTP_HOST'].'" class="purchase">Buy Lifetime License 18$</a>
</li>
</ul>
<span class="twoco">2Checkout.com Inc. (Ohio, USA) is a payment facilitator for goods and services provided by vestacp.com.</span>';
}
?>
</div>
</td>
</tr>
<tr>
<td class="vst-text" id="module-filemanager">
<?php print __('File Manager') ?>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<select class="vst-list" name="v_filemanager"> <select class="vst-list" name="v_filemanager">
<option value='no'><?php print __('no'); ?></option> <?
<option value='yes'><?php print __('yes'); ?></option> if($_SESSION['FILEMANAGER_KEY']){
echo '<option value="cancel">'.__('Disable and Cancel Licence').'</option>';
} else {
echo '<option value="no">'.__('no').'</option>';
}
?>
<option value='yes' <? if($_GET['lead'] == 'filemanager' || $_SESSION['FILEMANAGER_KEY']) echo 'selected="selected"'; ?>><?php print __('yes'); ?></option>
</select> </select>
<br><br> <br><br>
<div class="filemanager description" style="display:none"> <div class="filemanager description" <? if($_GET['lead'] != 'filemanager' && !$_SESSION['FILEMANAGER_KEY']) echo 'style="display:none"'; ?>>
Web Filemanager is a commercial module. By purchasing it you not only get powerfull filemanagement tool but also help VestaCP get better and stronger.<br> <?
You can see the bref video review of the module functionality.<br>
<span>(to try it free for a week please use "TMKE765" as a licence key)</span> if($_GET['filemanager_licence_key'] != '' || $_SESSION['FILEMANAGER_KEY']){
<div class="licence"> $licence_key = $_GET['filemanager_licence_key'] != '' ? $_GET['filemanager_licence_key'] : $_SESSION['FILEMANAGER_KEY'];
To activate filemanager insert licence key: <input type="text" class="vst-input" name="v_filemanager_licence" /><br> echo '
</div> Browse, copy, edit, view, and retrieve all of your web domain files using fully featured File Manager.
<ul>
<li><a class="purchase" href="read.com">get monthly licence 3$/month</a></li> <div class="licence">
<li><a class="purchase" href="read.com">get forever licence 50$</a></li> Licence Key: <input type="text" class="vst-input" name="v_filemanager_licence" value="'.$licence_key.'" /><br>
</ul> </div>';
} else {
echo '
Browse, copy, edit, view, and retrieve all of your web domain files using fully featured File Manager.
This is a commercial module, you would need to purchace license key to enable it.
<div class="licence">
Enter Licence Key: <input type="text" class="vst-input" name="v_filemanager_licence" /><br>
</div>
<ul>
<li>
<a href="https://vestacp.com/checkout/2co.php?demo=Y&product_id=7&referer='.$_SERVER['HTTP_HOST'].'" class="purchase">Buy Licence 3$/month</a>
</li>
<li>
<a href="https://vestacp.com/checkout/2co.php?demo=Y&product_id=8&referer='.$_SERVER['HTTP_HOST'].'" class="purchase">Buy Lifetime Licence 50$</a>
</li>
</ul>
<span class="twoco">2Checkout.com Inc. (Ohio, USA) is a payment facilitator for goods and services provided by vestacp.com.</span>';
}
?>
</div> </div>
</td> </td>
</tr> </tr>
@ -732,5 +808,13 @@
$('.filemanager.description').hide(); $('.filemanager.description').hide();
} }
}); });
});
$('select[name=v_sftp]').change(function(){
if($(this).val() == 'yes'){
$('.sftp.description').show();
} else {
$('.sftp.description').hide();
}
});
});
</script> </script>

View file

@ -383,13 +383,17 @@
}); });
$('.l-profile__notifications').click(function(){ $('.l-profile__notifications').click(function(){
$('.notification-container').toggle(); if(!$('.l-profile__notifications').hasClass('active')){
$('.l-profile__notifications').toggleClass('active'); VE.notifications.get_list();
$('.l-profile__notifications').addClass('active');
left = $('.l-profile__notifications').offset().left - $('.notification-container').outerWidth() + 28;
$('.notification-container').css({left: left+'px'});
left = $('.l-profile__notifications').offset().left - $('.notification-container').outerWidth() + 28; } else {
$('.notification-container').css({left: left+'px'}); $('.notification-container').hide();
$('.l-profile__notifications').removeClass('active');
}
}); });
VE.navigation.init(); VE.navigation.init();