[backport] enable angular-translate sanitize

stable
Juanfran 2015-11-11 09:48:22 +01:00
parent 569023e0f5
commit 6f3f757443
5 changed files with 45 additions and 63 deletions

View File

@ -510,6 +510,7 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
prefix: "/locales/locale-",
suffix: ".json"
})
.useSanitizeValueStrategy('escapeParameters')
.addInterpolation('$translateMessageFormatInterpolation')
.preferredLanguage(preferedLangCode)
@ -669,6 +670,7 @@ modules = [
"templates",
# Vendor modules
"ngSanitize",
"ngRoute",
"ngAnimate",
"ngAria",

View File

@ -135,27 +135,18 @@ CreatedByDisplayDirective = ($template, $compile, $translate, $navUrls)->
# 'owner'(ng-model)
# - scope.usersById object is required.
template = $template.get("common/components/created-by.html", true)
link = ($scope, $el, $attrs) ->
render = (model) ->
owner = model.owner_extra_info or {
bindOnce $scope, $attrs.ngModel, (model) ->
if model?
$scope.owner = model.owner_extra_info or {
full_name_display: $translate.instant("COMMON.EXTERNAL_USER")
photo: "/images/user-noimage.png"
}
html = template({
owner: owner
url: if owner?.is_active then $navUrls.resolve("user-profile", {username: owner.username}) else ""
date: moment(model.created_date).format($translate.instant("COMMON.DATETIME"))
})
$scope.url = if $scope.owner?.is_active then $navUrls.resolve("user-profile", {username: $scope.owner.username}) else ""
html = $compile(html)($scope)
$el.html(html)
bindOnce $scope, $attrs.ngModel, (model) ->
render(model) if model?
$scope.date = moment(model.created_date).format($translate.instant("COMMON.DATETIME"))
$scope.$on "$destroy", ->
$el.off()
@ -163,13 +154,14 @@ CreatedByDisplayDirective = ($template, $compile, $translate, $navUrls)->
return {
link: link
restrict: "EA"
require: "ngModel"
require: "ngModel",
scope: true,
templateUrl: "common/components/created-by.html"
}
module.directive("tgCreatedByDisplay", ["$tgTemplate", "$compile", "$translate", "$tgNavUrls",
CreatedByDisplayDirective])
#############################################################################
## Watchers directive
#############################################################################

View File

@ -21,7 +21,8 @@ unslugify = @.taiga.unslugify
class UserTimelineItemTitle
@.$inject = [
"$translate"
"$translate",
"$sce"
]
_fieldTranslationKey: {
@ -105,7 +106,7 @@ class UserTimelineItemTitle
return _.escape(timeline.getIn(['data', 'value_diff', 'value']).keySeq().first())
}
constructor: (@translate) ->
constructor: (@translate, @sce) ->
_translateTitleParams: (param, timeline, event) ->
@ -152,7 +153,18 @@ class UserTimelineItemTitle
return params
getTitle: (timeline, event, type) ->
return @translate.instant(type.key, @._getParams(timeline, event, type))
params = @._getParams(timeline, event, type)
paramsKeys = {}
Object.keys(params).forEach (key) -> paramsKeys[key] = '{{' +key + '}}'
translation = @translate.instant(type.key, paramsKeys)
Object.keys(params).forEach (key) ->
find = '{{' +key + '}}'
translation = translation.replace(new RegExp(find, 'g'), params[key])
return translation
angular.module("taigaUserTimeline")
.service("tgUserTimelineItemTitle", UserTimelineItemTitle)

View File

@ -72,12 +72,8 @@ describe "tgUserTimelineItemTitle", ->
.withArgs('COMMON.SEE_USER_PROFILE', {username: timeline.getIn(['data', 'user', 'username'])})
.returns('user-param')
usernamelink = sinon.match ((value) ->
return value.username == '<a tg-nav="user-profile:username=timeline.getIn([\'data\', \'user\', \'username\'])" title="user-param">oo</a>'
), "usernamelink"
mockTranslate.instant
.withArgs('TITLE_USER_NAME', usernamelink)
.withArgs('TITLE_USER_NAME', {username: '{{username}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -106,12 +102,8 @@ describe "tgUserTimelineItemTitle", ->
.withArgs('COMMON.SEE_USER_PROFILE', {username: timeline.getIn(['data', 'user', 'username'])})
.returns('user-param')
usernamelink = sinon.match ((value) ->
return value.username == '<span class="username">oo</span>'
), "usernamelink"
mockTranslate.instant
.withArgs('TITLE_USER_NAME', usernamelink)
.withArgs('TITLE_USER_NAME', {username: '{{username}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -138,12 +130,8 @@ describe "tgUserTimelineItemTitle", ->
.withArgs('COMMON.FIELDS.STATUS')
.returns('field-params')
fieldparam = sinon.match ((value) ->
return value.field_name == 'field-params'
), "fieldparam"
mockTranslate.instant
.withArgs('TITLE_FIELD', fieldparam)
.withArgs('TITLE_FIELD', {field_name: '{{field_name}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -168,7 +156,7 @@ describe "tgUserTimelineItemTitle", ->
}
mockTranslate.instant
.withArgs('NEW_VALUE', {new_value: 'new'})
.withArgs('NEW_VALUE', {new_value: '{{new_value}}'})
.returns('new_value_ok')
title = mySvc.getTitle(timeline, event, type)
@ -191,12 +179,8 @@ describe "tgUserTimelineItemTitle", ->
translate_params: ['project_name']
}
projectparam = sinon.match ((value) ->
return value.project_name == '<a tg-nav="project:project=timeline.getIn([\'data\', \'project\', \'slug\'])" title="project_name">project_name</a>'
), "projectparam"
mockTranslate.instant
.withArgs('TITLE_PROJECT', projectparam)
.withArgs('TITLE_PROJECT', {project_name: '{{project_name}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -224,7 +208,7 @@ describe "tgUserTimelineItemTitle", ->
), "milestoneparam"
mockTranslate.instant
.withArgs('TITLE_MILESTONE', milestoneparam)
.withArgs('TITLE_MILESTONE', {sprint_name: '{{sprint_name}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -250,12 +234,8 @@ describe "tgUserTimelineItemTitle", ->
translate_params: ['obj_name']
}
objparam = sinon.match ((value) ->
return value.obj_name == '<a tg-nav="project-issues-detail:project=timeline.getIn([\'data\', \'project\', \'slug\']),ref=timeline.getIn([\'obj\', \'ref\'])" title="#123 subject">#123 subject</a>'
), "objparam"
mockTranslate.instant
.withArgs('TITLE_OBJ', objparam)
.withArgs('TITLE_OBJ', obj_name: '{{obj_name}}')
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -280,12 +260,8 @@ describe "tgUserTimelineItemTitle", ->
translate_params: ['obj_name']
}
objparam = sinon.match ((value) ->
return value.obj_name == '<a tg-nav="project-wiki-page:project=timeline.getIn([\'data\', \'project\', \'slug\']),slug=timeline.getIn([\'obj\', \'slug\'])" title="Slug wiki">Slug wiki</a>'
), "objparam"
mockTranslate.instant
.withArgs('TITLE_OBJ', objparam)
.withArgs('TITLE_OBJ', {obj_name: '{{obj_name}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -315,7 +291,7 @@ describe "tgUserTimelineItemTitle", ->
), "objparam"
mockTranslate.instant
.withArgs('TITLE_OBJ', objparam)
.withArgs('TITLE_OBJ', {obj_name: '{{obj_name}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)
@ -349,7 +325,7 @@ describe "tgUserTimelineItemTitle", ->
), "objparam"
mockTranslate.instant
.withArgs('TITLE_OBJ', objparam)
.withArgs('TITLE_OBJ', {us_name: '{{us_name}}'})
.returns('title_ok')
title = mySvc.getTitle(timeline, event, type)

View File

@ -1,9 +1,9 @@
.user-avatar
a(href!="<%- url %>", title!="<%- owner.full_name_display %>")
img(src!="<%- owner.photo %>", alt!="<%- owner.full_name_display %>")
a(href="{{url}}", title="{{owner.full_name_display}}")
img(src="{{owner.photo}}", alt="{{owner.full_name_display}}")
.created-by
a(href!="<%- url %>", title!="<%- owner.full_name_display %>")
span.created-title(translate="COMMON.CREATED_BY", translate-values!="{ 'fullDisplayName': '<%- owner.full_name_display %>'}")
a(href="{{url}}", title="{{owner.full_name_display}}")
span.created-title(translate="COMMON.CREATED_BY", translate-values="{ 'fullDisplayName': owner.full_name_display}")
span.created-date
| <%- date %>
| {{date}}