Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MNOE-497] [WIP] Move rails pages to SPA #236

Open
wants to merge 18 commits into
base: 2.0
Choose a base branch
from
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
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"mno-ui-elements": "maestrano/mno-ui-elements#master",
"textAngular": "^1.5.16",
"json-formatter": "^0.6.0",
"es6-shim": "^0.35.3"
"es6-shim": "^0.35.3",
"AngularDevise": "angular-devise#^1.3.0"
},
"devDependencies": {
"angular-mocks": "~1.6.0"
Expand Down
23 changes: 13 additions & 10 deletions src/app/components/mno-errors-handler/mno-errors-handler.svc.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,32 @@ angular.module 'mnoEnterpriseAngular'
errorCache = null
mnoErrorHandler.processServerError = (serverError, form) ->
$log.error('An error occurred:', serverError)

return unless form

return if _.startsWith(serverError.data, '<!DOCTYPE html>')
if 400 <= serverError.status <= 499 # Error in the request
# Save the errors object in the scope
errorCache = serverError
errorCache = serverError.data.errors
# Set each error fields as not valid
_.each errorCache.data, (errors, key) ->
_.each errors, ->
if form[key]?
form[key].$setValidity 'server', false
else
$log.error('MnoErrorsHandler: cannot find field:' + key)
if form? && errorCache
_.each errorCache, (errors, key) ->
_.each errors, ->
if form[key]?
form[key].$setValidity 'server', false
else
$log.error('MnoErrorsHandler: cannot find field:' + key)

mnoErrorHandler.errorMessage = (name) ->
result = []
if errorCache?
_.each errorCache.data[name], (msg) ->
result.push msg
_.each errorCache[name], (msg) ->
result.push [ _.capitalize(name), msg ].join ' '
result.join ', '

mnoErrorHandler.resetErrors = (form) ->
if errorCache?
_.each errorCache.data, (errors, key) ->
_.each errorCache, (errors, key) ->
_.each errors, ->
if form[key]?
form[key].$setValidity 'server', null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ angular.module 'mnoEnterpriseAngular'

# Find the locale from the User#settings
localeFromUser = ->
MnoeCurrentUser.get().then(
MnoeCurrentUser.get(skip_login_check: true).then(
(response) ->
response.settings?.locale
)
Expand Down
149 changes: 149 additions & 0 deletions src/app/components/mno-password-strength/mno-password-strength.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
angular.module 'mnoEnterpriseAngular'
.directive 'mnoPasswordStrength', (MnoErrorsHandler) ->
require: "ngModel"
restrict: 'A'
scope:
passwordScore: '=' #outject score

link: (scope, element, attrs, ctrl) ->
measureStrength = (p) ->
matches =
pos: {}
neg: {}

counts =
pos: {}
neg:
seqLetter: 0
seqNumber: 0
seqSymbol: 0

tmp = undefined
strength = 0
letters = "abcdefghijklmnopqrstuvwxyz"
numbers = "01234567890"
symbols = "\\!@#$%&/()=?¿"
back = undefined
forth = undefined

if p
# Benefits
matches.pos.lower = p.match(/[a-z]/g)
matches.pos.upper = p.match(/[A-Z]/g)
matches.pos.numbers = p.match(/\d/g)
matches.pos.symbols = p.match(/[$-/:-?{-~!^_`\[\]]/g)
matches.pos.middleNumber = p.slice(1, -1).match(/\d/g)
matches.pos.middleSymbol = p.slice(1, -1).match(/[$-/:-?{-~!^_`\[\]]/g)
counts.pos.lower = (if matches.pos.lower then matches.pos.lower.length else 0)
counts.pos.upper = (if matches.pos.upper then matches.pos.upper.length else 0)
counts.pos.numbers = (if matches.pos.numbers then matches.pos.numbers.length else 0)
counts.pos.symbols = (if matches.pos.symbols then matches.pos.symbols.length else 0)
tmp = _.reduce(counts.pos, (memo, val) ->
# if has count will add 1
memo + Math.min(1, val)
, 0)
counts.pos.numChars = p.length
tmp += (if (counts.pos.numChars >= 8) then 1 else 0)
counts.pos.requirements = (if (tmp >= 3) then tmp else 0)
counts.pos.middleNumber = (if matches.pos.middleNumber then matches.pos.middleNumber.length else 0)
counts.pos.middleSymbol = (if matches.pos.middleSymbol then matches.pos.middleSymbol.length else 0)

# Deductions
matches.neg.consecLower = p.match(/(?=([a-z]{2}))/g)
matches.neg.consecUpper = p.match(/(?=([A-Z]{2}))/g)
matches.neg.consecNumbers = p.match(/(?=(\d{2}))/g)
matches.neg.onlyNumbers = p.match(/^[0-9]*$/g)
matches.neg.onlyLetters = p.match(/^([a-z]|[A-Z])*$/g)
counts.neg.consecLower = (if matches.neg.consecLower then matches.neg.consecLower.length else 0)
counts.neg.consecUpper = (if matches.neg.consecUpper then matches.neg.consecUpper.length else 0)
counts.neg.consecNumbers = (if matches.neg.consecNumbers then matches.neg.consecNumbers.length else 0)

# sequential letters (back and forth)
i = 0
while i < letters.length - 2
p2 = p.toLowerCase()
forth = letters.substring(i, parseInt(i + 3))
back = _(forth).split("").reverse()
counts.neg.seqLetter++ if p2.indexOf(forth) isnt -1 or p2.indexOf(back) isnt -1
i++

# sequential numbers (back and forth)
i = 0
while i < numbers.length - 2
forth = numbers.substring(i, parseInt(i + 3))
back = _(forth).split("").reverse()
counts.neg.seqNumber++ if p.indexOf(forth) isnt -1 or p.toLowerCase().indexOf(back) isnt -1
i++

# sequential symbols (back and forth)
i = 0
while i < symbols.length - 2
forth = symbols.substring(i, parseInt(i + 3))
back = _(forth).split("").reverse()
counts.neg.seqSymbol++ if p.indexOf(forth) isnt -1 or p.toLowerCase().indexOf(back) isnt -1
i++

# repeated chars
counts.neg.repeated = _.chain(p.toLowerCase().split("")).countBy((val) ->
val
).reject((val) ->
val is 1
).reduce((memo, val) ->
memo + val
, 0).value()

# Calculations
strength += counts.pos.numChars * 4
strength += (counts.pos.numChars - counts.pos.upper) * 2 if counts.pos.upper
strength += (counts.pos.numChars - counts.pos.lower) * 2 if counts.pos.lower
strength += counts.pos.numbers * 4 if counts.pos.upper or counts.pos.lower
strength += counts.pos.symbols * 6
strength += (counts.pos.middleSymbol + counts.pos.middleNumber) * 2
strength += counts.pos.requirements * 2
strength -= counts.neg.consecLower * 2
strength -= counts.neg.consecUpper * 2
strength -= counts.neg.consecNumbers * 2
strength -= counts.neg.seqNumber * 3
strength -= counts.neg.seqLetter * 3
strength -= counts.neg.seqSymbol * 3
strength -= counts.pos.numChars if matches.neg.onlyNumbers
strength -= counts.pos.numChars if matches.neg.onlyLetters
strength -= (counts.neg.repeated / counts.pos.numChars) * 10 if counts.neg.repeated
Math.max 0, Math.min(100, Math.round(strength))

getPwStrength = (s) ->
switch Math.round(s / 20)
when 0, 1
"weak"
when 2,3
"good"
when 4,5
"secure"

getClass = (s) ->
switch getPwStrength(s)
when 'weak'
"danger"
when 'good'
"warning"
when 'secure'
"success"

isPwStrong = (s) ->
switch getPwStrength(s)
when 'weak'
false
else
true

scope.$watch (-> ctrl.$modelValue), ->
scope.value = measureStrength(ctrl.$modelValue)
scope.pwStrength = getPwStrength(scope.value)
ctrl.$setValidity('password-strength', isPwStrong(scope.value))
if scope.passwordScore?
scope.passwordScore.value = scope.pwStrength
scope.passwordScore.class = getClass(scope.value)
scope.passwordScore.showTip = (ctrl.$modelValue? && ctrl.$modelValue != '' && !isPwStrong(scope.value))


return
6 changes: 6 additions & 0 deletions src/app/components/mnoe-api/auth.svc.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
angular.module 'mnoEnterpriseAngular'
.factory 'MnoeAuthSvc', (Restangular, inflector) ->
return Restangular.withConfig((RestangularProvider) ->
RestangularProvider.setBaseUrl('/mnoe/auth')
RestangularProvider.setDefaultHeaders({Accept: "application/json"})
)
37 changes: 24 additions & 13 deletions src/app/components/mnoe-api/current-user.svc.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# => PUT /mnoe/jpi/v1/current_user/update_password

angular.module 'mnoEnterpriseAngular'
.service 'MnoeCurrentUser', (MnoeApiSvc, $window, $state, $rootScope, URI, MnoeConfig) ->
.service 'MnoeCurrentUser', (MnoeApiSvc, $window, $state, $q, $timeout, $rootScope, URI, Auth, MnoeConfig) ->
_self = @

# Store the current_user promise
Expand All @@ -23,12 +23,34 @@ angular.module 'mnoEnterpriseAngular'
# Save the current user in variable to be able to reference it directly
@user = {}

# Redirect if user is already logged in
@skipIfLoggedIn = ->
Auth.currentUser().then(
(response) ->
$timeout( -> $state.go('home.impac') )
$q.reject()
->
$q.resolve()
)

@loginRequired = ->
Auth.currentUser().catch(
->
$timeout( -> $state.go('login') )
$q.reject()
)

# Get the current user
@get = ->
@get = (opts = {})->
return userPromise if userPromise?

userPromise = MnoeApiSvc.one('current_user').get().then(
(response) ->
response = response.plain()

if ! (opts.skip_login_check || response.logged_in)
$state.go('login')

angular.copy(response, _self.user)
response
)
Expand All @@ -55,15 +77,4 @@ angular.module 'mnoEnterpriseAngular'
@updatePassword = (passwordData) ->
MnoeApiSvc.all('/current_user').doPUT({user: passwordData}, 'update_password')

# Ensure user is logged in
@loginRequired = ->
_self.get().then(
(response) ->
unless response.logged_in
if MnoeConfig.arePublicApplicationsEnabled()
$state.go('public.landing')
else
$window.location = URI.login
)

return @
27 changes: 24 additions & 3 deletions src/app/index.config.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ angular.module 'mnoEnterpriseAngular'
)

.config ($httpProvider) ->
$httpProvider.interceptors.push ($q, $window) ->
$httpProvider.interceptors.push ($q, $window, $injector, $log) ->
{
responseError: (rejection) ->
if rejection.status == 401
# Redirect to login page
console.log "User is not connected!"
$window.location.href = '/'
toastr = $injector.get('toastr')

toastr.error('User is not connected!')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should i18n this toastr

$log.error('User is not connected!')

$q.reject rejection
}
Expand Down Expand Up @@ -84,3 +86,22 @@ angular.module 'mnoEnterpriseAngular'
# TODO: Activate in "developer mode" only (spams the console and makes the application lag)
# $translateProvider.useMissingTranslationHandlerLog()
)
# Configure auth routes
.config((AuthProvider, AuthInterceptProvider) ->
AuthProvider.loginPath('/mnoe/auth/users/sign_in')
AuthProvider.logoutPath('/mnoe/auth/users/sign_out')
AuthProvider.registerPath('/mnoe/auth/users/')
AuthProvider.sendResetPasswordInstructionsPath('/mnoe/auth/users/password')
AuthProvider.resetPasswordPath('/mnoe/auth/users/password')
AuthInterceptProvider.interceptAuth(true)
)










Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove empty lines

6 changes: 3 additions & 3 deletions src/app/index.constants.coffee
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
angular.module 'mnoEnterpriseAngular'
.constant('URI', {
login: '/mnoe/auth/users/sign_in',
login: '/login',
dashboard: '/dashboard/',
logout: '/mnoe/auth/users/sign_out',
signup: '/mnoe/auth/users/sign_up',
api_root: '/mnoe/jpi/v1'
api_root: '/mnoe/jpi/v1',
logout: '/logout'
})
.constant('DOC_LINKS', {
connecDoc: 'https://maestrano.atlassian.net/wiki/x/BIHLAQ'
Expand Down
1 change: 1 addition & 0 deletions src/app/index.default-config.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ angular.module('mnoEnterprise.defaultConfiguration', [])
.constant('APP_NAME', null)
.constant('INTERCOM_ID', null)
.constant('URL_CONFIG', {})
.constant('DEVISE_CONFIG', {})
2 changes: 1 addition & 1 deletion src/app/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ body {
}
}

.myspace {
.myspace, .page-wrapper {
background-color: @dashboard-bg-color;
min-height:100%;
}
Expand Down
4 changes: 3 additions & 1 deletion src/app/index.module.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ angular.module 'mnoEnterpriseAngular', [
'schemaForm',
'angular.filter',
'textAngular',
'jsonFormatter'
'jsonFormatter',
'mnoUiElements',
'Devise'
]
Loading