mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #1540 from sharelatex/ns-less-spam-mail
add spam checkers on project invite emails GitOrigin-RevId: 305825efe6a824b1c0f5b347d2ed2427165d2cef
This commit is contained in:
parent
f5ecc5ad85
commit
f699877959
6 changed files with 601 additions and 31 deletions
|
@ -6,6 +6,7 @@ StringHelper = require "../Helpers/StringHelper"
|
|||
PersonalEmailLayout = require("./Layouts/PersonalEmailLayout")
|
||||
NotificationEmailLayout = require("./Layouts/NotificationEmailLayout")
|
||||
BaseWithHeaderEmailLayout = require("./Layouts/" + settings.brandPrefix + "BaseWithHeaderEmailLayout")
|
||||
SpamSafe = require("./SpamSafe")
|
||||
|
||||
SingleCTAEmailBody = require("./Bodies/" + settings.brandPrefix + "SingleCTAEmailBody")
|
||||
|
||||
|
@ -101,20 +102,20 @@ templates.confirmEmail = CTAEmailTemplate({
|
|||
})
|
||||
|
||||
templates.projectInvite = CTAEmailTemplate({
|
||||
subject: (opts) -> "#{ _.escape(opts.project.name) } - shared by #{ _.escape(opts.owner.email) }"
|
||||
title: (opts) -> "#{ _.escape(opts.project.name) } - shared by #{ _.escape(opts.owner.email) }"
|
||||
message: (opts) -> "#{ _.escape(opts.owner.email) } wants to share '#{ _.escape(opts.project.name) }' with you."
|
||||
subject: (opts) -> "#{ _.escape(SpamSafe.safeProjectName(opts.project.name, "New Project")) } - shared by #{ _.escape(SpamSafe.safeEmail(opts.owner.email, "a collaborator")) }"
|
||||
title: (opts) -> "#{ _.escape(SpamSafe.safeProjectName(opts.project.name, "New Project")) } - shared by #{ _.escape(SpamSafe.safeEmail(opts.owner.email, "a collaborator")) }"
|
||||
message: (opts) -> "#{ _.escape(SpamSafe.safeEmail(opts.owner.email, "a collaborator")) } wants to share '#{ _.escape(SpamSafe.safeProjectName(opts.project.name, "a new Project")) }' with you."
|
||||
ctaText: () -> "View project"
|
||||
ctaURL: (opts) -> opts.inviteUrl
|
||||
gmailGoToAction: (opts) ->
|
||||
target: opts.inviteUrl
|
||||
name: "View project"
|
||||
description: "Join #{ _.escape(opts.project.name) } at #{ settings.appName }"
|
||||
description: "Join #{ _.escape(SpamSafe.safeProjectName(opts.project.name, "Project")) } at #{ settings.appName }"
|
||||
})
|
||||
|
||||
templates.verifyEmailToJoinTeam = CTAEmailTemplate({
|
||||
subject: (opts) -> "#{ _.escape(opts.inviterName) } has invited you to join a team on #{ settings.appName }"
|
||||
title: (opts) -> "#{ _.escape(opts.inviterName) } has invited you to join a team on #{ settings.appName }"
|
||||
subject: (opts) -> "#{ _.escape(SpamSafe.safeUserName(opts.inviterName, "A collaborator")) } has invited you to join a team on #{ settings.appName }"
|
||||
title: (opts) -> "#{ _.escape(SpamSafe.safeUserName(opts.inviterName, "A collaborator")) } has invited you to join a team on #{ settings.appName }"
|
||||
message: (opts) -> "Please click the button below to join the team and enjoy the benefits of an upgraded #{ settings.appName } account."
|
||||
ctaText: (opts) -> "Join now"
|
||||
ctaURL: (opts) -> opts.acceptInviteUrl
|
||||
|
|
38
services/web/app/coffee/Features/Email/SpamSafe.coffee
Normal file
38
services/web/app/coffee/Features/Email/SpamSafe.coffee
Normal file
|
@ -0,0 +1,38 @@
|
|||
XRegExp = require('xregexp')
|
||||
|
||||
# A note about SAFE_REGEX:
|
||||
# We have to escape the escape characters because XRegExp compiles it first.
|
||||
# So it's equivalent to `^[\p{L}\p{N}\s\-_!&\(\)]+$]
|
||||
# \p{L} = any letter in any language
|
||||
# \p{N} = any kind of numeric character
|
||||
# https://www.regular-expressions.info/unicode.html#prop is a good resource for
|
||||
# more obscure regex features. standard RegExp does not support these
|
||||
|
||||
SAFE_REGEX = XRegExp("^[\\p{L}\\p{N}\\s\\-_!&\\(\\)]+$")
|
||||
EMAIL_REGEX = XRegExp("^[\\p{L}\\p{N}.+_-]+@[\\w.]+$")
|
||||
|
||||
SpamSafe =
|
||||
isSafeUserName: (name) ->
|
||||
SAFE_REGEX.test(name) && name.length <= 30
|
||||
|
||||
isSafeProjectName: (name) ->
|
||||
if XRegExp("\\p{Han}").test(name)
|
||||
SAFE_REGEX.test(name) && name.length <= 30
|
||||
SAFE_REGEX.test(name) && name.length <= 100
|
||||
|
||||
isSafeEmail: (email) ->
|
||||
EMAIL_REGEX.test(email) && email.length <= 40
|
||||
|
||||
safeUserName: (name, alternative, project = false) ->
|
||||
return name if SpamSafe.isSafeUserName name
|
||||
alternative
|
||||
|
||||
safeProjectName: (name, alternative) ->
|
||||
return name if SpamSafe.isSafeProjectName name
|
||||
alternative
|
||||
|
||||
safeEmail: (email, alternative) ->
|
||||
return email if SpamSafe.isSafeEmail email
|
||||
alternative
|
||||
|
||||
module.exports = SpamSafe
|
530
services/web/npm-shrinkwrap.json
generated
530
services/web/npm-shrinkwrap.json
generated
|
@ -16,6 +16,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@babel/runtime-corejs2": {
|
||||
"version": "7.3.1",
|
||||
"from": "@babel/runtime-corejs2@>=7.2.0 <8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.3.1.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "2.6.5",
|
||||
"from": "core-js@>=2.5.7 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz"
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.12.1",
|
||||
"from": "regenerator-runtime@>=0.12.0 <0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@contentful/axios": {
|
||||
"version": "0.18.0",
|
||||
"from": "@contentful/axios@>=0.18.0 <0.19.0",
|
||||
|
@ -1897,7 +1914,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"readdirp": {
|
||||
|
@ -2000,7 +2017,7 @@
|
|||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"from": "source-map@~0.6.0",
|
||||
"from": "source-map@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"dev": true
|
||||
}
|
||||
|
@ -2210,7 +2227,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@>=2.2.2 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz"
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
|
@ -4142,6 +4159,466 @@
|
|||
"from": "fs.realpath@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "1.2.7",
|
||||
"from": "fsevents@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"from": "abbrev@1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"from": "ansi-regex@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"from": "aproba@^1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"from": "are-we-there-yet@~1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"from": "balanced-match@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"from": "brace-expansion@^1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.1",
|
||||
"from": "chownr@^1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"from": "code-point-at@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"from": "concat-map@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"from": "console-control-strings@~1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"from": "core-util-is@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"from": "debug@^2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"from": "deep-extend@^0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"from": "delegates@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"from": "detect-libc@^1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"from": "fs-minipass@^1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"from": "fs.realpath@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"from": "gauge@~2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"from": "glob@^7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"from": "has-unicode@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"from": "iconv-lite@^0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"from": "ignore-walk@^3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"from": "inflight@^1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"from": "inherits@~2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"from": "ini@~1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"from": "is-fullwidth-code-point@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"from": "isarray@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"from": "minimatch@^3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"from": "minimist@0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"from": "minipass@^2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"from": "safe-buffer@^5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.2.1",
|
||||
"from": "minizlib@^1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"from": "mkdirp@^0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"from": "ms@2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.12.1",
|
||||
"from": "nan@>=2.9.2 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.2.4",
|
||||
"from": "needle@^2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.10.3",
|
||||
"from": "node-pre-gyp@^0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"from": "nopt@^4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.5",
|
||||
"from": "npm-bundled@^1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.2.0",
|
||||
"from": "npm-packlist@^1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.2.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"from": "npmlog@^4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"from": "number-is-nan@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"from": "object-assign@^4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"from": "os-homedir@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"from": "os-tmpdir@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"from": "osenv@^0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"from": "path-is-absolute@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"from": "process-nextick-args@>=2.0.0 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.8",
|
||||
"from": "rc@^1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"from": "minimist@^1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@>=2.0.6 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"from": "rimraf@^2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"from": "safer-buffer@>= 2.1.2 < 3",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"from": "sax@^1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"from": "set-blocking@~2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"from": "signal-exit@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"from": "string_decoder@>=1.1.1 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"from": "string-width@^1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"from": "strip-ansi@^3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"from": "strip-json-comments@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.8",
|
||||
"from": "tar@^4",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"from": "safe-buffer@>=5.1.2 <6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"from": "util-deprecate@~1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"from": "wide-align@^1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"from": "wrappy@1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"from": "yallist@>=3.0.2 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"fstream": {
|
||||
"version": "1.0.11",
|
||||
"from": "fstream@>=1.0.2 <2.0.0",
|
||||
|
@ -4172,6 +4649,13 @@
|
|||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"xregexp": {
|
||||
"version": "2.0.0",
|
||||
"from": "xregexp@2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4286,7 +4770,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
|
@ -4973,7 +5457,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -5956,7 +6440,7 @@
|
|||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"from": "minimist@1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
|
@ -7189,7 +7673,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -7221,7 +7705,7 @@
|
|||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"from": "minimist@>=1.1.3 <2.0.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"path-exists": {
|
||||
|
@ -7390,7 +7874,7 @@
|
|||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"from": "minimist@1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.4",
|
||||
|
@ -7797,7 +8281,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -8154,7 +8638,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"readdirp": {
|
||||
|
@ -9574,7 +10058,7 @@
|
|||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"from": "minimist@>=1.2.0 <2.0.0",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -10720,7 +11204,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.2.9",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -10815,7 +11299,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -10853,7 +11337,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -10896,7 +11380,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
|
@ -12218,7 +12702,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"readdirp": {
|
||||
|
@ -12422,7 +12906,7 @@
|
|||
"chokidar": {
|
||||
"version": "2.0.3",
|
||||
"from": "chokidar@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
|
||||
"resolved": "http://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
|
@ -12842,7 +13326,7 @@
|
|||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"from": "readable-stream@^2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"dev": true
|
||||
},
|
||||
"readdirp": {
|
||||
|
@ -13176,11 +13660,9 @@
|
|||
"resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz"
|
||||
},
|
||||
"xregexp": {
|
||||
"version": "2.0.0",
|
||||
"from": "xregexp@2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"version": "4.2.4",
|
||||
"from": "xregexp@4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.4.tgz"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
"v8-profiler": "^5.2.3",
|
||||
"valid-url": "^1.0.9",
|
||||
"xml2js": "0.2.0",
|
||||
"xregexp": "^4.2.4",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -50,5 +50,25 @@ describe "EmailBuilder", ->
|
|||
@email = @EmailBuilder.buildEmail("projectInvite", @opts)
|
||||
|
||||
it 'should not contain unescaped html in the html part', ->
|
||||
expect(@email.html).to.contain "<img"
|
||||
expect(@email.html).to.contain "New Project"
|
||||
|
||||
it "should not have undefined in it", ->
|
||||
@email.html.indexOf("undefined").should.equal -1
|
||||
@email.subject.indexOf("undefined").should.equal -1
|
||||
|
||||
describe "SpamSafe", ->
|
||||
beforeEach ->
|
||||
@opts =
|
||||
to:"bob@joe.com"
|
||||
first_name:"bob"
|
||||
owner:
|
||||
email:"sally@hally.com"
|
||||
inviteUrl: "http://example.com/invite"
|
||||
project:
|
||||
url:"http://www.project.com"
|
||||
name:"come buy my product at http://notascam.com"
|
||||
@email = @EmailBuilder.buildEmail("projectInvite", @opts)
|
||||
|
||||
it "should replace spammy project name", ->
|
||||
@email.html.indexOf("a new Project").should.not.equal -1
|
||||
@email.subject.indexOf("New Project").should.not.equal -1
|
||||
|
|
28
services/web/test/unit/coffee/Email/SpamSafeTests.coffee
Normal file
28
services/web/test/unit/coffee/Email/SpamSafeTests.coffee
Normal file
|
@ -0,0 +1,28 @@
|
|||
path = require('path')
|
||||
modulePath = path.join __dirname, "../../../../app/js/Features/Email/SpamSafe"
|
||||
SpamSafe = require(modulePath)
|
||||
expect = require("chai").expect
|
||||
|
||||
describe "SpamSafe", ->
|
||||
|
||||
it 'should reject spammy names', ->
|
||||
expect(SpamSafe.isSafeUserName("Charline Wałęsa")).to.equal true
|
||||
expect(SpamSafe.isSafeUserName("hey come buy this product im selling it's really good for you and it'll make your latex 10x guaranteed")).to.equal false
|
||||
expect(SpamSafe.isSafeUserName("隆太郎 宮本")).to.equal true
|
||||
expect(SpamSafe.isSafeUserName("Visit haxx0red.com")).to.equal false
|
||||
expect(SpamSafe.isSafeUserName('加美汝VX:hihi661,金沙2001005com the first deposit will be _100%_')).to.equal false
|
||||
expect(SpamSafe.isSafeProjectName('Neural Networks: good for your health and will solve all your problems')).to.equal false
|
||||
expect(SpamSafe.isSafeProjectName("An analysis of the questions of the universe!")).to.equal true
|
||||
expect(SpamSafe.isSafeProjectName('come buy this => http://www.dopeproduct.com/search/?q=user123')).to.equal false
|
||||
expect(SpamSafe.isSafeEmail("realistic-email+1@domain.sub.com")).to.equal true
|
||||
expect(SpamSafe.isSafeEmail("notquiteRight\@evil$.com")).to.equal false
|
||||
|
||||
expect(SpamSafe.safeUserName("Tammy Weinstįen", "A User")).to.equal "Tammy Weinstįen"
|
||||
expect(SpamSafe.safeUserName("haxx0red.com", "A User")).to.equal "A User"
|
||||
expect(SpamSafe.safeUserName("What$ Upp", "A User")).to.equal "A User"
|
||||
expect(SpamSafe.safeProjectName("Math-ematics!", "A Project")).to.equal "Math-ematics!"
|
||||
expect(SpamSafe.safeProjectName("A Very long title for a very long book that will never be read" + "a".repeat(250), "A Project")).to.equal "A Project"
|
||||
expect(SpamSafe.safeEmail("safe-ëmail@domain.com", "A collaborator")).to.equal "safe-ëmail@domain.com"
|
||||
expect(SpamSafe.safeEmail("Բարեւ@another.domain", "A collaborator")).to.equal "Բարեւ@another.domain"
|
||||
expect(SpamSafe.safeEmail("me+" + "a".repeat(40) + "@googoole.con", "A collaborator")).to.equal "A collaborator"
|
||||
expect(SpamSafe.safeEmail("sendME$$$@iAmAprince.com", "A collaborator")).to.equal "A collaborator"
|
Loading…
Reference in a new issue