overleaf/services/web/public/coffee/directives/asyncForm.coffee

169 lines
5 KiB
CoffeeScript
Raw Normal View History

2014-07-08 07:02:26 -04:00
define [
"base"
2015-04-24 09:33:01 -04:00
"libs/passfield"
2014-07-08 07:02:26 -04:00
], (App) ->
App.directive "asyncForm", ($http, validateCaptcha) ->
2014-07-08 07:02:26 -04:00
return {
controller: ['$scope', ($scope) ->
@getEmail = () ->
return $scope.email
return this
]
2014-07-08 07:02:26 -04:00
link: (scope, element, attrs) ->
formName = attrs.asyncForm
scope[attrs.name].response = response = {}
scope[attrs.name].inflight = false
2014-07-08 07:02:26 -04:00
validateCaptchaIfEnabled = (callback = (response) ->) ->
if attrs.captcha?
validateCaptcha callback
else
callback()
2017-12-11 08:31:16 -05:00
submitRequest = (grecaptchaResponse) ->
2014-07-08 07:02:26 -04:00
formData = {}
for data in element.serializeArray()
formData[data.name] = data.value
if grecaptchaResponse?
formData['g-recaptcha-response'] = grecaptchaResponse
scope[attrs.name].inflight = true
2016-11-04 11:44:12 -04:00
# for asyncForm prevent automatic redirect to /login if
# authentication fails, we will handle it ourselves
2014-07-08 07:02:26 -04:00
$http
2016-11-04 11:44:12 -04:00
.post(element.attr('action'), formData, {disableAutoLoginRedirect: true})
.then (httpResponse) ->
{ data, status, headers, config } = httpResponse
scope[attrs.name].inflight = false
2014-07-08 07:02:26 -04:00
response.success = true
response.error = false
onSuccessHandler = scope[attrs.onSuccess]
if onSuccessHandler
onSuccessHandler(httpResponse)
return
2014-07-08 07:02:26 -04:00
if data.redir?
ga('send', 'event', formName, 'success')
window.location = data.redir
else if data.message?
response.message = data.message
if data.message.type == "error"
response.success = false
response.error = true
ga('send', 'event', formName, 'failure', data.message)
else
ga('send', 'event', formName, 'success')
.catch (httpResponse) ->
{ data, status, headers, config } = httpResponse
scope[attrs.name].inflight = false
2014-07-08 07:02:26 -04:00
response.success = false
response.error = true
onErrorHandler = scope[attrs.onError]
if onErrorHandler
onErrorHandler(httpResponse)
return
2018-10-04 05:36:22 -04:00
if status == 400 # Bad Request
response.message =
text: "Invalid Request. Please correct the data and try again."
type: 'error'
else if status == 403 # Forbidden
response.message =
text: "Session error. Please check you have cookies enabled. If the problem persists, try clearing your cache and cookies."
type: "error"
else
response.message =
text: data.message?.text or data.message or "Something went wrong talking to the server :(. Please try again."
type: 'error'
2014-07-08 07:02:26 -04:00
ga('send', 'event', formName, 'failure', data.message)
submit = () ->
validateCaptchaIfEnabled (response) ->
submitRequest response
element.on "submit", (e) ->
e.preventDefault()
submit()
if attrs.autoSubmit
submit()
2014-07-08 07:02:26 -04:00
}
App.directive "formMessages", () ->
return {
restrict: "E"
template: """
<div class="alert" ng-class="{
'alert-danger': form.response.message.type == 'error',
'alert-success': form.response.message.type != 'error'
}" ng-show="!!form.response.message">
{{form.response.message.text}}
</div>
<div ng-transclude></div>
"""
transclude: true
scope: {
form: "=for"
}
}
2015-04-24 09:33:01 -04:00
App.directive 'complexPassword', ->
require: ['^asyncForm', 'ngModel']
link: (scope, element, attrs, ctrl) ->
2015-04-24 09:33:01 -04:00
PassField.Config.blackList = []
defaultPasswordOpts =
pattern: ""
length:
min: 6
max: 128
allowEmpty: false
allowAnyChars: false
isMasked: true
showToggle: false
showGenerate: false
showTip:false
showWarn:false
checkMode : PassField.CheckModes.STRICT
chars:
digits: "1234567890"
letters: "abcdefghijklmnopqrstuvwxyz"
letters_up: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
symbols: "@#$%^&*()-_=+[]{};:<>/?!£€.,"
opts = _.defaults(window.passwordStrengthOptions || {}, defaultPasswordOpts)
if opts.length.min == 1
opts.acceptRate = 0 #this allows basically anything to be a valid password
2015-04-28 12:50:06 -04:00
passField = new PassField.Field("passwordField", opts);
[asyncFormCtrl, ngModelCtrl] = ctrl
ngModelCtrl.$parsers.unshift (modelValue) ->
2015-04-24 09:33:01 -04:00
isValid = passField.validatePass()
email = asyncFormCtrl.getEmail() || window.usersEmail
if !isValid
scope.complexPasswordErrorMessage = passField.getPassValidationMessage()
else if (email? and email != "")
startOfEmail = email?.split("@")?[0]
if modelValue.indexOf(email) != -1 or modelValue.indexOf(startOfEmail) != -1
isValid = false
scope.complexPasswordErrorMessage = "Password can not contain email address"
2016-09-23 10:44:47 -04:00
if opts.length.max? and modelValue.length == opts.length.max
isValid = false
scope.complexPasswordErrorMessage = "Maximum password length #{opts.length.max} reached"
if opts.length.min? and modelValue.length < opts.length.min
isValid = false
scope.complexPasswordErrorMessage = "Password too short, minimum #{opts.length.min}"
ngModelCtrl.$setValidity('complexPassword', isValid)
return modelValue