asyncForm.coffee 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. define [
  2. "base"
  3. "libs/passfield"
  4. ], (App) ->
  5. App.directive "asyncForm", ($http) ->
  6. return {
  7. controller: ['$scope', ($scope) ->
  8. @getEmail = () ->
  9. return $scope.email
  10. return this
  11. ]
  12. link: (scope, element, attrs) ->
  13. formName = attrs.asyncForm
  14. scope[attrs.name].response = response = {}
  15. scope[attrs.name].inflight = false
  16. element.on "submit", (e) ->
  17. e.preventDefault()
  18. formData = {}
  19. for data in element.serializeArray()
  20. formData[data.name] = data.value
  21. scope[attrs.name].inflight = true
  22. # for asyncForm prevent automatic redirect to /login if
  23. # authentication fails, we will handle it ourselves
  24. $http
  25. .post(element.attr('action'), formData, {disableAutoLoginRedirect: true})
  26. .success (data, status, headers, config) ->
  27. scope[attrs.name].inflight = false
  28. response.success = true
  29. response.error = false
  30. onSuccessHandler = scope[attrs.onSuccess]
  31. if onSuccessHandler
  32. onSuccessHandler(data, status, headers, config)
  33. return
  34. if data.redir?
  35. ga('send', 'event', formName, 'success')
  36. window.location = data.redir
  37. else if data.message?
  38. response.message = data.message
  39. if data.message.type == "error"
  40. response.success = false
  41. response.error = true
  42. ga('send', 'event', formName, 'failure', data.message)
  43. else
  44. ga('send', 'event', formName, 'success')
  45. .error (data, status, headers, config) ->
  46. scope[attrs.name].inflight = false
  47. response.success = false
  48. response.error = true
  49. onErrorHandler = scope[attrs.onError]
  50. if onErrorHandler
  51. onErrorHandler(data, status, headers, config)
  52. return
  53. if status == 403 # Forbidden
  54. response.message =
  55. text: "Session error. Please check you have cookies enabled. If the problem persists, try clearing your cache and cookies."
  56. type: "error"
  57. else
  58. response.message =
  59. text: data.message?.text or data.message or "Something went wrong talking to the server :(. Please try again."
  60. type: 'error'
  61. ga('send', 'event', formName, 'failure', data.message)
  62. }
  63. App.directive "formMessages", () ->
  64. return {
  65. restrict: "E"
  66. template: """
  67. <div class="alert" ng-class="{
  68. 'alert-danger': form.response.message.type == 'error',
  69. 'alert-success': form.response.message.type != 'error'
  70. }" ng-show="!!form.response.message">
  71. {{form.response.message.text}}
  72. </div>
  73. <div ng-transclude></div>
  74. """
  75. transclude: true
  76. scope: {
  77. form: "=for"
  78. }
  79. }
  80. App.directive 'complexPassword', ->
  81. require: ['^asyncForm', 'ngModel']
  82. link: (scope, element, attrs, ctrl) ->
  83. PassField.Config.blackList = []
  84. defaultPasswordOpts =
  85. pattern: ""
  86. length:
  87. min: 1
  88. max: 50
  89. allowEmpty: false
  90. allowAnyChars: false
  91. isMasked: true
  92. showToggle: false
  93. showGenerate: false
  94. showTip:false
  95. showWarn:false
  96. checkMode : PassField.CheckModes.STRICT
  97. chars:
  98. digits: "1234567890"
  99. letters: "abcdefghijklmnopqrstuvwxyz"
  100. letters_up: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  101. symbols: "@#$%^&*()-_=+[]{};:<>/?!£€.,"
  102. opts = _.defaults(window.passwordStrengthOptions || {}, defaultPasswordOpts)
  103. if opts.length.min == 1
  104. opts.acceptRate = 0 #this allows basically anything to be a valid password
  105. passField = new PassField.Field("passwordField", opts);
  106. [asyncFormCtrl, ngModelCtrl] = ctrl
  107. ngModelCtrl.$parsers.unshift (modelValue) ->
  108. isValid = passField.validatePass()
  109. email = asyncFormCtrl.getEmail() || window.usersEmail
  110. if !isValid
  111. scope.complexPasswordErrorMessage = passField.getPassValidationMessage()
  112. else if (email? and email != "")
  113. startOfEmail = email?.split("@")?[0]
  114. if modelValue.indexOf(email) != -1 or modelValue.indexOf(startOfEmail) != -1
  115. isValid = false
  116. scope.complexPasswordErrorMessage = "Password can not contain email address"
  117. if opts.length.max? and modelValue.length == opts.length.max
  118. isValid = false
  119. scope.complexPasswordErrorMessage = "Maximum password length #{opts.length.max} reached"
  120. ngModelCtrl.$setValidity('complexPassword', isValid)
  121. return modelValue