Commit 6752cdc3 by GD-A-150752

MR-Changes

parent 5e8fcfdb
...@@ -8,14 +8,24 @@ export const PERMISSIONS = { ...@@ -8,14 +8,24 @@ export const PERMISSIONS = {
CAN_UPDATE_SETTINGS: 'CAN_UPDATE_SETTINGS', CAN_UPDATE_SETTINGS: 'CAN_UPDATE_SETTINGS',
CAN_ACCESS_SETTINGS: 'CAN_ACCESS_SETTINGS', CAN_ACCESS_SETTINGS: 'CAN_ACCESS_SETTINGS',
CAN_ACCESS_EMAIL_TEMPLATES: 'CAN_ACCESS_EMAIL_TEMPLATES', CAN_ACCESS_EMAIL_TEMPLATES: 'CAN_ACCESS_EMAIL_TEMPLATES',
CAN_UPDATE_ALL_USERS: 'CAN_UPDATE_ALL_USERS',
}; };
export enum ROLE_RANK {
ADMIN = 1,
USER,
BLOCKED,
}
export const CONFIG = { export const CONFIG = {
SiteName: 'JIBC', SiteName: 'JIBC',
}; };
export const ERR = {
EMAIL_EXISTS: 'Email address already in use.',
EMAIL_NOT_EXISTS: 'Email address doesn\'t exist.',
ID_MISSING: 'UserId is missing',
EMAIL_MISSING: 'Email is missing',
DATA_MISSING: 'Required fields are missing',
FORBIDDEN: 'Not Enough Permissions',
};
export const E_CODE = {
UNPROCESSABLE_ENTITY: 422,
SERVER_ERROR: 500,
FORBIDDEN: 403,
};
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import { EmailService } from '../services/email.service'; import { EmailService } from '../services/email.service';
import { E_CODE, ERR } from '../config';
Meteor.methods({ Meteor.methods({
sendForgotPasswordEmail(email: string): boolean { sendForgotPasswordEmail(email: string): boolean {
...@@ -8,6 +9,6 @@ Meteor.methods({ ...@@ -8,6 +9,6 @@ Meteor.methods({
EmailService.sendForgotPasswordEmail(user, email); EmailService.sendForgotPasswordEmail(user, email);
return true; return true;
} }
throw new Meteor.Error(422, 'Email address doesn\'t exist.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.EMAIL_NOT_EXISTS);
}, },
}); });
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import { rolesCollection } from '../collections/role.collection'; import { rolesCollection } from '../collections/role.collection';
import { PERMISSIONS, ROLE_RANK } from '../config'; import { E_CODE, PERMISSIONS } from '../config';
import { RoleModel } from '../models/role.model'; import { RoleModel } from '../models/role.model';
import { UtilsService } from '../services/utils.service'; import { UtilsService } from '../services/utils.service';
...@@ -14,11 +14,7 @@ Meteor.methods({ ...@@ -14,11 +14,7 @@ Meteor.methods({
.toPromise(); .toPromise();
} }
} catch (e) { } catch (e) {
throw new Meteor.Error('Unable to add.', JSON.stringify(e)); throw new Meteor.Error(E_CODE.SERVER_ERROR, JSON.stringify(e));
} }
}, },
getRoleSlug(id): ROLE_RANK {
return rolesCollection.findOne(id).Slug;
},
}); });
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import { PERMISSIONS } from '../config'; import { E_CODE, ERR, PERMISSIONS } from '../config';
import { UtilsService } from '../services/utils.service'; import { UtilsService } from '../services/utils.service';
import { settingsCollection } from '../collections/setting.collections'; import { settingsCollection } from '../collections/setting.collections';
...@@ -10,7 +10,7 @@ Meteor.methods({ ...@@ -10,7 +10,7 @@ Meteor.methods({
Object.keys(setting) Object.keys(setting)
.forEach(key => settingsCollection.update({ Key: key }, { $set: { Value: setting[key] } })); .forEach(key => settingsCollection.update({ Key: key }, { $set: { Value: setting[key] } }));
} else { } else {
throw new Meteor.Error(403, 'Not Enough Permissions'); throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
} }
}, },
...@@ -25,7 +25,7 @@ Meteor.methods({ ...@@ -25,7 +25,7 @@ Meteor.methods({
}, },
}); });
} else { } else {
throw new Meteor.Error(403, 'Not Enough Permissions'); throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
} }
}, },
}); });
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import { rolesCollection } from '../collections/role.collection'; import { rolesCollection } from '../collections/role.collection';
import { PERMISSIONS } from '../config'; import { ERR, E_CODE, PERMISSIONS } from '../config';
import { UtilsService } from '../services/utils.service'; import { UtilsService } from '../services/utils.service';
import { EmailService } from '../services/email.service'; import { EmailService } from '../services/email.service';
...@@ -8,6 +8,7 @@ Meteor.methods({ ...@@ -8,6 +8,7 @@ Meteor.methods({
registerUser(user: any): string { registerUser(user: any): string {
const defaultRole = rolesCollection.findOne({ title: user.role }); const defaultRole = rolesCollection.findOne({ title: user.role });
if (!Accounts.findUserByEmail(user.email)) { if (!Accounts.findUserByEmail(user.email)) {
const userObj = { const userObj = {
email: user.email, email: user.email,
...@@ -24,7 +25,7 @@ Meteor.methods({ ...@@ -24,7 +25,7 @@ Meteor.methods({
return userId; return userId;
} }
throw new Meteor.Error(422, 'Email address already in use.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.EMAIL_EXISTS);
}, },
verifyEmailAddress(user: any): any { verifyEmailAddress(user: any): any {
...@@ -34,47 +35,61 @@ Meteor.methods({ ...@@ -34,47 +35,61 @@ Meteor.methods({
return true; return true;
} }
throw new Meteor.Error(422, 'Email address already in use.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.EMAIL_EXISTS);
}, },
updateUser(user: any): any { updateUser(user: any): any {
if (!UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_OWN_USER)) { if (!user._id) {
throw new Meteor.Error(403, 'Forbidden.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.ID_MISSING);
} }
if (user._id) { if (UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_ALL_USERS) ||
(
UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_OWN_USER)
&& user._id === Meteor.user()._id
)) {
const updateObj = { $set: { profile: user.profile } }; const updateObj = { $set: { profile: user.profile } };
return Meteor.users.update(user._id, updateObj); return Meteor.users.update(user._id, updateObj);
} }
throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
}, },
addEmailAddress(user: any): any { addEmailAddress(user: any): any {
if (!UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_OWN_USER)) { if (!user._id || !user.email) {
throw new Meteor.Error(403, 'Forbidden.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.DATA_MISSING);
} }
if (Accounts.findUserByEmail(user.email)) { if (Accounts.findUserByEmail(user.email)) {
throw new Meteor.Error(422, 'Email address already in use.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.EMAIL_EXISTS);
} }
if (user._id && user.email) { if (UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_ALL_USERS) ||
(
UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_OWN_USER)
&& user._id === Meteor.user()._id
)) {
Accounts.addEmail(user._id, user.email); Accounts.addEmail(user._id, user.email);
return true; return true;
} }
throw new Meteor.Error(500, 'Email Address is missing.'); throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
}, },
removeEmailAddress(user: any): any { removeEmailAddress(user: any): any {
if (!UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_OWN_USER)) { if (!user._id || !user.email) {
throw new Meteor.Error(403, 'Forbidden.'); throw new Meteor.Error(E_CODE.UNPROCESSABLE_ENTITY, ERR.DATA_MISSING);
} }
if (user._id && user.email) { if (UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_ALL_USERS) ||
(
UtilsService.hasPermission(PERMISSIONS.CAN_UPDATE_OWN_USER)
&& user._id === Meteor.user()._id
)) {
Accounts.removeEmail(user._id, user.email); Accounts.removeEmail(user._id, user.email);
return true; return true;
} }
throw new Meteor.Error(500, 'Email Address is missing.');
throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
}, },
checkUserByEmail(email: string): any { checkUserByEmail(email: string): any {
......
import { settingsCollection } from './collections/setting.collections'; import { settingsCollection } from './collections/setting.collections';
import { PERMISSIONS, ROLE_RANK } from './config'; import { PERMISSIONS } from './config';
import { rolesCollection } from './collections/role.collection'; import { rolesCollection } from './collections/role.collection';
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
...@@ -15,19 +15,17 @@ Migrations.add({ ...@@ -15,19 +15,17 @@ Migrations.add({
title: 'Admin', title: 'Admin',
permissions: allPermissions, permissions: allPermissions,
description: '', description: '',
Slug: ROLE_RANK.ADMIN,
}); });
rolesCollection.insert({ rolesCollection.insert({
title: 'User', title: 'User',
permissions: [PERMISSIONS.CAN_LOGIN, PERMISSIONS.CAN_UPDATE_OWN_USER], permissions: [PERMISSIONS.CAN_LOGIN, PERMISSIONS.CAN_UPDATE_OWN_USER,
PERMISSIONS.CAN_ACCESS_DASHBOARD_PAGE],
description: '', description: '',
Slug: ROLE_RANK.USER,
}); });
rolesCollection.insert({ rolesCollection.insert({
title: 'Blocked', title: 'Blocked',
permissions: [], permissions: [],
description: '', description: '',
Slug: ROLE_RANK.BLOCKED,
}); });
} else { } else {
rolesCollection.update({ title: 'Admin' }, { $set: { permissions: allPermissions } }); rolesCollection.update({ title: 'Admin' }, { $set: { permissions: allPermissions } });
......
import { ROLE_RANK } from '../config';
export interface RoleModel { export interface RoleModel {
_id?: string; _id?: string;
title: string; title: string;
permissions: string[]; permissions: string[];
Slug: ROLE_RANK;
description: string; description: string;
} }
import { settingsCollection } from '../collections/setting.collections'; import { settingsCollection } from '../collections/setting.collections';
import { UtilsService } from '../services/utils.service'; import { UtilsService } from '../services/utils.service';
import { PERMISSIONS } from '../config'; import { E_CODE, ERR, PERMISSIONS } from '../config';
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
Meteor.publish('settings', () => { Meteor.publish('settings', (filter: any = {}) => {
if (UtilsService.hasPermission(PERMISSIONS.CAN_ACCESS_SETTINGS)) { if (UtilsService.hasPermission(PERMISSIONS.CAN_ACCESS_SETTINGS)) {
return settingsCollection.find({}); if (filter.IsEmail && !UtilsService.hasPermission(PERMISSIONS.CAN_ACCESS_EMAIL_TEMPLATES)) {
throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
}
return settingsCollection.find(filter);
} }
throw new Meteor.Error(403, 'Not Enough Permissions'); throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
});
Meteor.publish('email-templates', () => {
if (UtilsService.hasPermission(PERMISSIONS.CAN_ACCESS_EMAIL_TEMPLATES)) {
return settingsCollection.find({ IsEmail: true });
}
throw new Meteor.Error(403, 'Not Enough Permissions');
}); });
...@@ -2,7 +2,7 @@ import { Meteor } from 'meteor/meteor'; ...@@ -2,7 +2,7 @@ import { Meteor } from 'meteor/meteor';
// tslint:disable-next-line:ban-ts-ignore // tslint:disable-next-line:ban-ts-ignore
// @ts-ignore // @ts-ignore
import { publishComposite } from 'meteor/reywood:publish-composite'; import { publishComposite } from 'meteor/reywood:publish-composite';
import { PERMISSIONS } from '../config'; import { E_CODE, ERR, PERMISSIONS } from '../config';
import { QueryModel } from '../models/query.model'; import { QueryModel } from '../models/query.model';
import { UtilsService } from '../services/utils.service'; import { UtilsService } from '../services/utils.service';
import { rolesCollection } from '../collections/role.collection'; import { rolesCollection } from '../collections/role.collection';
...@@ -12,7 +12,7 @@ publishComposite('usersList', (filters = {}) => { ...@@ -12,7 +12,7 @@ publishComposite('usersList', (filters = {}) => {
const queryFilters = { ...new QueryModel(), ...filters }; const queryFilters = { ...new QueryModel(), ...filters };
if (!UtilsService.hasPermission([PERMISSIONS.CAN_SEE_ALL_USERS])) { if (!UtilsService.hasPermission([PERMISSIONS.CAN_SEE_ALL_USERS])) {
throw new Meteor.Error(403, 'Not enough permissions to get all users'); throw new Meteor.Error(E_CODE.FORBIDDEN, ERR.FORBIDDEN);
} }
return { return {
......
...@@ -5,48 +5,74 @@ import { rolesCollection } from '../collections/role.collection'; ...@@ -5,48 +5,74 @@ import { rolesCollection } from '../collections/role.collection';
export class EmailService { export class EmailService {
static sendVerificationEmail(user: any, userId: string, email = false): void { static sendVerificationEmail(user: any, userId: string, email = false): void {
Accounts.emailTemplates.siteName = CONFIG.SiteName; Accounts.emailTemplates.siteName = CONFIG.SiteName;
const mail = email ? email : user.emails[0].address;
const defaultRole = rolesCollection.findOne(user.profile.role); const defaultRole = rolesCollection.findOne(user.profile.role);
// Will uncomment it later with domain email // Will uncomment it later with domain email
// Accounts.emailTemplates.from = CONFIG.DomainEmail; // Accounts.emailTemplates.from = CONFIG.DomainEmail;
Accounts.emailTemplates.verifyEmail = { Accounts.emailTemplates.verifyEmail = {
subject() { subject() {
const content: any = settingsCollection.findOne({ Key: 'REGISTER' }); const content: any = settingsCollection.findOne({ Key: 'REGISTER' });
return content ? content.Value.SUBJECT.replace('$platform', CONFIG.SiteName) : 'Welcome';
if (content) {
return EmailService.formattedContent(
content.Value.SUBJECT, user.profile.name, defaultRole.title, mail);
}
return 'Welcome';
}, },
html(usr, url) { html(usr, url) {
const token = url.substr(url.lastIndexOf('/') + 1); const token = url.substr(url.lastIndexOf('/') + 1);
const link = `${process.env.appUrl}#/auth/verify-email/${token}`; const link = `${process.env.appUrl}#/auth/verify-email/${token}`;
const content: any = settingsCollection.findOne({ Key: 'REGISTER' }); const content: any = settingsCollection.findOne({ Key: 'REGISTER' });
return content.Value.CONTENT.replace(/\$name/g, user.profile.name)
.replace(/\$role/g, defaultRole.title) return EmailService.formattedContent(
.replace(/\$link/g, link); content.Value.CONTENT, user.profile.name, defaultRole.title, mail, link);
}, },
}; };
const mail = email ? email : user.emails[0].address;
Accounts.sendVerificationEmail(userId, mail); Accounts.sendVerificationEmail(userId, mail);
} }
static sendForgotPasswordEmail(user: Meteor.User, email: string): void { static sendForgotPasswordEmail(user: Meteor.User, email: string): void {
Accounts.emailTemplates.siteName = CONFIG.SiteName; Accounts.emailTemplates.siteName = CONFIG.SiteName;
const mail = email ? email : user.emails[0].address;
const defaultRole = rolesCollection.findOne(user.profile.role);
// Will uncomment it later with domain email // Will uncomment it later with domain email
// Accounts.emailTemplates.from = CONFIG.DomainEmail; // Accounts.emailTemplates.from = CONFIG.DomainEmail;
Accounts.emailTemplates.resetPassword = { Accounts.emailTemplates.resetPassword = {
subject() { subject() {
const content: any = settingsCollection.findOne({ Key: 'RESET' }); const content: any = settingsCollection.findOne({ Key: 'RESET' });
return content ? content.Value.SUBJECT.replace('$platform', CONFIG.SiteName) : 'Welcome';
if (content) {
return EmailService.formattedContent(
content.Value.SUBJECT, user.profile.name, defaultRole.title, mail);
}
return 'Reset Password';
}, },
html(usr, url) { html(usr, url) {
const token = url.substr(url.lastIndexOf('/') + 1); const token = url.substr(url.lastIndexOf('/') + 1);
const link = `${process.env.appUrl}#/auth/reset-password/${token}`; const link = `${process.env.appUrl}#/auth/reset-password/${token}`;
const content: any = settingsCollection.findOne({ Key: 'RESET' }); const content: any = settingsCollection.findOne({ Key: 'RESET' });
return content.Value.CONTENT.replace(/\$name/g, user.profile.name)
.replace(/\$link/g, link); return EmailService.formattedContent(
content.Value.CONTENT, user.profile.name, defaultRole.title, mail, link);
}, },
}; };
Accounts.sendResetPasswordEmail(user._id, email); Accounts.sendResetPasswordEmail(user._id, email);
} }
static formattedContent(content: string, name: string, role: string, email, link = null): string {
const str = content.replace(/\$name/g, name)
.replace(/\$role/g, role)
.replace(/\$platform/g, CONFIG.SiteName)
.replace(/\$email/g, email);
return link ? str.replace(/\$link/g, link) : str;
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment