// Sandstorm context is detected using the METEOR_SETTINGS environment variable
// in the package definition.
const isSandstorm =
Meteor . settings && Meteor . settings . public && Meteor . settings . public . sandstorm ;
Settings = new Mongo . Collection ( 'settings' ) ;
Settings . attachSchema (
new SimpleSchema ( {
disableRegistration : {
type : Boolean ,
} ,
'mailServer.username' : {
type : String ,
optional : true ,
} ,
'mailServer.password' : {
type : String ,
optional : true ,
} ,
'mailServer.host' : {
type : String ,
optional : true ,
} ,
'mailServer.port' : {
type : String ,
optional : true ,
} ,
'mailServer.enableTLS' : {
type : Boolean ,
optional : true ,
} ,
'mailServer.from' : {
type : String ,
optional : true ,
} ,
productName : {
type : String ,
optional : true ,
} ,
displayAuthenticationMethod : {
type : Boolean ,
optional : true ,
} ,
defaultAuthenticationMethod : {
type : String ,
optional : false ,
} ,
hideLogo : {
type : Boolean ,
optional : true ,
} ,
customLoginLogoImageUrl : {
type : String ,
optional : true ,
} ,
customLoginLogoLinkUrl : {
type : String ,
optional : true ,
} ,
textBelowCustomLoginLogo : {
type : String ,
optional : true ,
} ,
automaticLinkedUrlSchemes : {
type : String ,
optional : true ,
} ,
customTopLeftCornerLogoImageUrl : {
type : String ,
optional : true ,
} ,
customTopLeftCornerLogoLinkUrl : {
type : String ,
optional : true ,
} ,
customTopLeftCornerLogoHeight : {
type : String ,
optional : true ,
} ,
createdAt : {
type : Date ,
denyUpdate : true ,
// eslint-disable-next-line consistent-return
autoValue ( ) {
if ( this . isInsert ) {
return new Date ( ) ;
} else if ( this . isUpsert ) {
return { $setOnInsert : new Date ( ) } ;
} else {
this . unset ( ) ;
}
} ,
} ,
modifiedAt : {
type : Date ,
// eslint-disable-next-line consistent-return
autoValue ( ) {
if ( this . isInsert || this . isUpsert || this . isUpdate ) {
return new Date ( ) ;
} else {
this . unset ( ) ;
}
} ,
} ,
} ) ,
) ;
Settings . helpers ( {
mailUrl ( ) {
if ( ! this . mailServer . host ) {
return null ;
}
const protocol = this . mailServer . enableTLS ? 'smtps://' : 'smtp://' ;
if ( ! this . mailServer . username && ! this . mailServer . password ) {
return ` ${ protocol } ${ this . mailServer . host } : ${ this . mailServer . port } / ` ;
}
return ` ${ protocol } ${ this . mailServer . username } : ${ encodeURIComponent (
this . mailServer . password ,
) } @ $ { this . mailServer . host } : $ { this . mailServer . port } / ` ;
} ,
} ) ;
Settings . allow ( {
update ( userId ) {
const user = Users . findOne ( userId ) ;
return user && user . isAdmin ;
} ,
} ) ;
if ( Meteor . isServer ) {
Meteor . startup ( ( ) => {
Settings . _collection . _ensureIndex ( { modifiedAt : - 1 } ) ;
const setting = Settings . findOne ( { } ) ;
if ( ! setting ) {
const now = new Date ( ) ;
const domain = process . env . ROOT _URL . match (
/\/\/(?:www\.)?(.*)?(?:\/)?/ ,
) [ 1 ] ;
const from = ` Boards Support <support@ ${ domain } > ` ;
const defaultSetting = {
disableRegistration : false ,
mailServer : {
username : '' ,
password : '' ,
host : '' ,
port : '' ,
enableTLS : false ,
from ,
} ,
createdAt : now ,
modifiedAt : now ,
displayAuthenticationMethod : true ,
defaultAuthenticationMethod : 'password' ,
} ;
Settings . insert ( defaultSetting ) ;
}
if ( isSandstorm ) {
// At Sandstorm, Admin Panel has SMTP settings
const newSetting = Settings . findOne ( ) ;
if ( ! process . env . MAIL _URL && newSetting . mailUrl ( ) )
process . env . MAIL _URL = newSetting . mailUrl ( ) ;
Accounts . emailTemplates . from = process . env . MAIL _FROM
? process . env . MAIL _FROM
: newSetting . mailServer . from ;
} else {
// Not running on Sandstorm, so using environment variables
Accounts . emailTemplates . from = process . env . MAIL _FROM ;
}
} ) ;
if ( isSandstorm ) {
// At Sandstorm Wekan Admin Panel, save SMTP settings.
Settings . after . update ( ( userId , doc , fieldNames ) => {
// assign new values to mail-from & MAIL_URL in environment
if ( _ . contains ( fieldNames , 'mailServer' ) && doc . mailServer . host ) {
const protocol = doc . mailServer . enableTLS ? 'smtps://' : 'smtp://' ;
if ( ! doc . mailServer . username && ! doc . mailServer . password ) {
process . env . MAIL _URL = ` ${ protocol } ${ doc . mailServer . host } : ${ doc . mailServer . port } / ` ;
} else {
process . env . MAIL _URL = ` ${ protocol } ${
doc . mailServer . username
} : $ { encodeURIComponent ( doc . mailServer . password ) } @ $ {
doc . mailServer . host
} : $ { doc . mailServer . port } / ` ;
}
Accounts . emailTemplates . from = doc . mailServer . from ;
}
} ) ;
}
function getRandomNum ( min , max ) {
const range = max - min ;
const rand = Math . random ( ) ;
return min + Math . round ( rand * range ) ;
}
function getEnvVar ( name ) {
const value = process . env [ name ] ;
if ( value ) {
return value ;
}
throw new Meteor . Error ( [
'var-not-exist' ,
` The environment variable ${ name } does not exist ` ,
] ) ;
}
function sendInvitationEmail ( _id ) {
const icode = InvitationCodes . findOne ( _id ) ;
const author = Users . findOne ( Meteor . userId ( ) ) ;
try {
const params = {
email : icode . email ,
inviter : Users . findOne ( icode . authorId ) . username ,
user : icode . email . split ( '@' ) [ 0 ] ,
icode : icode . code ,
url : FlowRouter . url ( 'sign-up' ) ,
} ;
const lang = author . getLanguage ( ) ;
Email . send ( {
to : icode . email ,
from : Accounts . emailTemplates . from ,
subject : TAPi18n . _ _ ( 'email-invite-register-subject' , params , lang ) ,
text : TAPi18n . _ _ ( 'email-invite-register-text' , params , lang ) ,
} ) ;
} catch ( e ) {
InvitationCodes . remove ( _id ) ;
throw new Meteor . Error ( 'email-fail' , e . message ) ;
}
}
function isLdapEnabled ( ) {
return (
process . env . LDAP _ENABLE === 'true' || process . env . LDAP _ENABLE === true
) ;
}
function isOauth2Enabled ( ) {
return (
process . env . OAUTH2 _ENABLED === 'true' ||
process . env . OAUTH2 _ENABLED === true
) ;
}
function isCasEnabled ( ) {
return (
process . env . CAS _ENABLED === 'true' || process . env . CAS _ENABLED === true
) ;
}
function isApiEnabled ( ) {
return process . env . WITH _API === 'true' || process . env . WITH _API === true ;
}
Meteor . methods ( {
sendInvitation ( emails , boards ) {
check ( emails , [ String ] ) ;
check ( boards , [ String ] ) ;
const user = Users . findOne ( Meteor . userId ( ) ) ;
if ( ! user . isAdmin ) {
throw new Meteor . Error ( 'not-allowed' ) ;
}
emails . forEach ( email => {
if ( email && SimpleSchema . RegEx . Email . test ( email ) ) {
// Checks if the email is already link to an account.
const userExist = Users . findOne ( { email } ) ;
if ( userExist ) {
throw new Meteor . Error (
'user-exist' ,
` The user with the email ${ email } has already an account. ` ,
) ;
}
// Checks if the email is already link to an invitation.
const invitation = InvitationCodes . findOne ( { email } ) ;
if ( invitation ) {
InvitationCodes . update ( invitation , {
$set : { boardsToBeInvited : boards } ,
} ) ;
sendInvitationEmail ( invitation . _id ) ;
} else {
const code = getRandomNum ( 100000 , 999999 ) ;
InvitationCodes . insert (
{
code ,
email ,
boardsToBeInvited : boards ,
createdAt : new Date ( ) ,
authorId : Meteor . userId ( ) ,
} ,
function ( err , _id ) {
if ( ! err && _id ) {
sendInvitationEmail ( _id ) ;
} else {
throw new Meteor . Error (
'invitation-generated-fail' ,
err . message ,
) ;
}
} ,
) ;
}
}
} ) ;
} ,
sendSMTPTestEmail ( ) {
if ( ! Meteor . userId ( ) ) {
throw new Meteor . Error ( 'invalid-user' ) ;
}
const user = Meteor . user ( ) ;
if ( ! user . emails || ! user . emails [ 0 ] || ! user . emails [ 0 ] . address ) {
throw new Meteor . Error ( 'email-invalid' ) ;
}
this . unblock ( ) ;
const lang = user . getLanguage ( ) ;
try {
Email . send ( {
to : user . emails [ 0 ] . address ,
from : Accounts . emailTemplates . from ,
subject : TAPi18n . _ _ ( 'email-smtp-test-subject' , { lng : lang } ) ,
text : TAPi18n . _ _ ( 'email-smtp-test-text' , { lng : lang } ) ,
} ) ;
} catch ( { message } ) {
throw new Meteor . Error (
'email-fail' ,
` ${ TAPi18n . _ _ ( 'email-fail-text' , { lng : lang } )}: ${ message } ` ,
message ,
) ;
}
return {
message : 'email-sent' ,
email : user . emails [ 0 ] . address ,
} ;
} ,
getCustomUI ( ) {
const setting = Settings . findOne ( { } ) ;
if ( ! setting . productName ) {
return {
productName : '' ,
} ;
} else {
return {
productName : ` ${ setting . productName } ` ,
} ;
}
} ,
getMatomoConf ( ) {
return {
address : getEnvVar ( 'MATOMO_ADDRESS' ) ,
siteId : getEnvVar ( 'MATOMO_SITE_ID' ) ,
doNotTrack : process . env . MATOMO _DO _NOT _TRACK || false ,
withUserName : process . env . MATOMO _WITH _USERNAME || false ,
} ;
} ,
_isLdapEnabled ( ) {
return isLdapEnabled ( ) ;
} ,
_isOauth2Enabled ( ) {
return isOauth2Enabled ( ) ;
} ,
_isCasEnabled ( ) {
return isCasEnabled ( ) ;
} ,
_isApiEnabled ( ) {
return isApiEnabled ( ) ;
} ,
// Gets all connection methods to use it in the Template
getAuthenticationsEnabled ( ) {
return {
ldap : isLdapEnabled ( ) ,
oauth2 : isOauth2Enabled ( ) ,
cas : isCasEnabled ( ) ,
} ;
} ,
getDefaultAuthenticationMethod ( ) {
return process . env . DEFAULT _AUTHENTICATION _METHOD ;
} ,
isPasswordLoginDisabled ( ) {
return process . env . PASSWORD _LOGIN _ENABLED === 'false' ;
} ,
} ) ;
}
export default Settings ;