Browse Source

Fixes #3875 - Add custom link to the login page.

Florian Liebe 2 years ago
parent
commit
69980d97ca

+ 14 - 0
app/assets/javascripts/app/controllers/login.coffee

@@ -42,6 +42,13 @@ class Login extends App.ControllerFullPage
     @controllerBind('ui:rerender', =>
       @render()
     )
+    @publicLinksSubscribeId = App.PublicLink.subscribe(=>
+      @render()
+    )
+
+  release: =>
+    if @publicLinksSubscribeId
+      App.PublicLink.unsubscribe(@publicLinksSubscribeId)
 
   render: (data = {}) ->
     auth_provider_all = App.Config.get('auth_provider_all')
@@ -50,10 +57,17 @@ class Login extends App.ControllerFullPage
       if @Config.get(provider.config) is true || @Config.get(provider.config) is 'true'
         auth_providers.push provider
 
+    public_links = App.PublicLink.search(
+      filter:
+        screen: ['login']
+      sortBy: 'prio'
+    )
+
     @replaceWith App.view('login')(
       item:           data
       logoUrl:        @logoUrl()
       auth_providers: auth_providers
+      public_links:   public_links
     )
 
     # set focus to username or password

+ 24 - 2
app/assets/javascripts/app/controllers/password_reset.coffee

@@ -23,13 +23,27 @@ class PasswordReset extends App.ControllerFullPage
     @title __('Reset Password')
     @navupdate '#password_reset'
 
+    @publicLinksSubscribeId = App.PublicLink.subscribe(=>
+      @render()
+    )
+
     @render()
 
-  render: (params) ->
+  release: =>
+    if @publicLinksSubscribeId
+      App.PublicLink.unsubscribe(@publicLinksSubscribeId)
+
+  render: (params = {}) ->
     configure_attributes = [
       { name: 'username', display: __('Enter your username or email address'), tag: 'input', type: 'text', limit: 100, null: false, class: 'input span4' }
     ]
 
+    params['public_links'] = App.PublicLink.search(
+      filter:
+        screen: ['password_reset']
+      sortBy: 'prio'
+    )
+
     @replaceWith(App.view('password/reset')(params))
 
     @form = new App.ControllerForm(
@@ -58,6 +72,14 @@ class PasswordReset extends App.ControllerFullPage
     )
 
   success: (data) =>
-    @html(App.view('password/reset_sent')())
+    public_links = App.PublicLink.search(
+      filter:
+        screen: ['password_reset']
+      sortBy: 'prio'
+    )
+
+    @html(App.view('password/reset_sent')(
+      public_links: public_links
+    ))
 
 App.Config.set('password_reset', PasswordReset, 'Routes')

+ 30 - 11
app/assets/javascripts/app/controllers/password_reset_verify.coffee

@@ -22,25 +22,31 @@ class PasswordResetVerify extends App.ControllerFullPage
     @title __('Reset Password')
     @navupdate '#password_reset_verify'
 
-    # get data
-    params =
-      token: @token
-    @ajax(
-      id:          'password_reset_verify'
-      type:        'POST'
-      url:         "#{@apiPath}/users/password_reset_verify"
-      data:        JSON.stringify(params)
-      processData: true
-      success:     @renderChange
+    @publicLinksSubscribeId = App.PublicLink.subscribe(=>
+      @verify_token()
     )
 
+    @verify_token()
+
+  release: =>
+    if @publicLinksSubscribeId
+      App.PublicLink.unsubscribe(@publicLinksSubscribeId)
+
   renderChange: (data) =>
+    public_links = App.PublicLink.search(
+      filter:
+        screen: ['password_reset']
+      sortBy: 'prio'
+    )
+
     if data.message is 'ok'
       configure_attributes = [
         { name: 'password', display: __('Password'), tag: 'input', type: 'password', limit: 100, null: false, class: 'input' }
       ]
 
-      @replaceWith(App.view('password/reset_change')())
+      @replaceWith(App.view('password/reset_change')(
+        public_links: public_links
+      ))
 
       new App.ControllerForm(
         el:        @el.find('.js-password')
@@ -51,6 +57,7 @@ class PasswordResetVerify extends App.ControllerFullPage
       @replaceWith(App.view('password/reset_failed')(
         head:    __('Reset Password failed!')
         message: __('Token is invalid!')
+        public_links: public_links
       ))
 
   submit: (e) ->
@@ -138,4 +145,16 @@ class PasswordResetVerify extends App.ControllerFullPage
         )
       @formEnable(@$('form'))
 
+  verify_token: ->
+    params =
+      token: @token
+    @ajax(
+      id:          'password_reset_verify'
+      type:        'POST'
+      url:         "#{@apiPath}/users/password_reset_verify"
+      data:        JSON.stringify(params)
+      processData: true
+      success:     @renderChange
+    )
+
 App.Config.set('password_reset_verify/:token', PasswordResetVerify, 'Routes')

+ 43 - 0
app/assets/javascripts/app/controllers/public_link.coffee

@@ -0,0 +1,43 @@
+class PublicLink extends App.ControllerSubContent
+  requiredPermission: 'admin.public_link'
+  header: __('Public Links')
+  constructor: ->
+    super
+
+    @genericController = new App.ControllerGenericIndex(
+      el: @el
+      id: @id
+      genericObject: 'PublicLink'
+      defaultSortBy: 'prio'
+      pageData:
+        home: 'public_links'
+        object: __('Public Link')
+        objects: __('Public Links')
+        navupdate: '#public_links'
+        notes: [
+          __('Public Links are …')
+        ]
+        buttons: [
+          { name: __('New Public Link'), 'data-type': 'new', class: 'btn--success' }
+        ]
+      container: @el.closest('.content')
+      veryLarge: true
+      dndCallback: (e, item) =>
+        items = @el.find('table > tbody > tr')
+        prios = []
+        prio = 0
+        for item in items
+          prio += 1
+          id = $(item).data('id')
+          prios.push [id, prio]
+
+        @ajax(
+          id:          'public_links_prio'
+          type:        'POST'
+          url:         "#{@apiPath}/public_links_prio"
+          processData: true
+          data:        JSON.stringify(prios: prios)
+        )
+    )
+
+App.Config.set('Public Links', { prio: 3325, name: __('Public Links'), parent: '#manage', target: '#manage/public_links', controller: PublicLink, permission: ['admin.public_links'] }, 'NavBarAdmin')

+ 23 - 2
app/assets/javascripts/app/controllers/signup.coffee

@@ -18,11 +18,26 @@ class Signup extends App.ControllerFullPage
     @title __('Sign up')
     @navupdate '#signup'
 
+    @publicLinksSubscribeId = App.PublicLink.subscribe(=>
+      @render()
+    )
+
     @render()
 
+  release: =>
+    if @publicLinksSubscribeId
+      App.PublicLink.unsubscribe(@publicLinksSubscribeId)
+
   render: ->
+    public_links = App.PublicLink.search(
+      filter:
+        screen: ['signup']
+      sortBy: 'prio'
+    )
 
-    @replaceWith(App.view('signup')())
+    @replaceWith App.view('signup')(
+      public_links: public_links
+    )
 
     @form = new App.ControllerForm(
       el:        @el.find('form')
@@ -69,8 +84,14 @@ class Signup extends App.ControllerFullPage
     # save user
     user.save(
       done: (r) =>
+        public_links = App.PublicLink.search(
+          filter:
+            screen: ['signup']
+          sortBy: 'prio'
+        )
         @replaceWith(App.view('signup/verify')(
-          email: @params.email
+          email:        @params.email
+          public_links: public_links
         ))
       fail: (settings, details) =>
         @formEnable(e)

+ 10 - 2
app/assets/javascripts/app/models/_application_model.coffee

@@ -842,9 +842,17 @@ set new attributes of model (remove already available attributes)
 
   @_filter: (collection, filter) ->
     for key, value of filter
+      filterValue = value
+      if !_.isArray(filterValue)
+        filterValue = [filterValue]
+
       collection = _.filter(collection, (item) ->
-        if item[key] is value
-          return item
+        itemValue = item[key]
+        if !_.isArray(itemValue)
+          itemValue = [itemValue]
+
+        for value in filterValue
+          return item if _.contains(itemValue, value)
       )
     collection
 

+ 24 - 0
app/assets/javascripts/app/models/public_link.coffee

@@ -0,0 +1,24 @@
+class App.PublicLink extends App.Model
+  @configure 'PublicLink', 'link', 'title', 'description', 'screen', 'new_tab', 'prio'
+  @extend Spine.Model.Ajax
+  @url: @apiPath + '/public_links'
+  @configure_attributes = [
+    { name: 'link', display: __('Link'), tag: 'input', type: 'text', limit: 500, 'null': false, placeholder: 'https://link' },
+    { name: 'title', display: __('Title'), tag: 'input', type: 'text', limit: 200, 'null': false },
+    { name: 'description', display: __('Description (shown as title tag for screen readers)'), tag: 'input', type: 'text', limit: 200, 'null': true },
+    { name: 'screen', display: __('Context'), tag: 'multiselect', options: { login: __('Login Screen'), signup: __('Signup Screen'), password_reset: __('Forgot Password Screen') }, default: ['login'], 'null': false,  },
+    { name: 'new_tab', display: __('Display in new tab'), tag: 'select', options: { true: __('yes'), false: __('no'), }, default: true, 'null': false },
+    { name: 'prio', display: __('Prio'), readonly: 1 },
+  ]
+
+  @configure_delete = true
+  @configure_clone = true
+  @configure_overview = [
+    'title',
+    'link',
+    'new_tab',
+  ]
+
+  @description = __('''
+You can define links which are shown e.g. in the footer of Zammad's login screen. These have many purposes, such as displaying a data privacy page for all people using your Zammad instance.
+''')

+ 8 - 7
app/assets/javascripts/app/views/login.jst.eco

@@ -34,10 +34,6 @@
           </div>
 
           <div class="form-group">
-    <!--
-            <label for="remember_me"><%- @Ti('Remember me') %></label>
-            <input id="remember_me" name="remember_me" value="1" type="checkbox"/>
-    -->
             <label class="inline-label checkbox-replacement">
               <input name="remember_me" value="1" type="checkbox">
               <%- @Icon('checkbox', 'icon-unchecked') %>
@@ -81,12 +77,17 @@
         <% end %>
       </p>
 
-    <% if @C('user_create_account'): %>
+    <% if @C('user_create_account') || @public_links: %>
       <hr>
       <p>
-        <a href="#signup"><%- @T('Register as a new customer') %></a>
+        <% if @C('user_create_account'): %>
+          <a href="#signup"><%- @T('Register as a new customer') %></a>
+        <% end %>
+        <% for link, link_index in @public_links: %>
+          <% if link_index > 0 || @C('user_create_account'): %> | <% end %>
+          <a href="<%= link.link %>" title="<% if link.description: %><%= link.description %><% else: %><%= link.title %><% end %>"<% if link.new_tab: %> target="_blank"<% end %>><%= link.title %></a>
+        <% end %>
       </p>
-    <% end %>
     </div>
   </div>
   <div class="poweredBy">

+ 13 - 0
app/assets/javascripts/app/views/password/reset.jst.eco

@@ -10,5 +10,18 @@
         </div>
       </form>
     </div>
+  <% if @public_links: %>
+    <p>
+      <% for link, link_index in @public_links: %>
+        <% if link_index > 0: %> | <% end %>
+        <a href="<%= link.link %>" title="<% if link.description: %><%= link.description %><% else: %><%= link.title %><% end %>"<% if link.new_tab: %> target="_blank"<% end %>><%= link.title %></a>
+      <% end %>
+    </p>
+  <% end %>
+  </div>
+  <div class="poweredBy">
+    <a href="https://zammad.org" target="_blank"><%- @Icon('logo') %></a>
+    <%- @T('Powered by') %>
+    <a href="https://zammad.org" target="_blank"><%- @Icon('logotype', 'logotype') %></a>
   </div>
 </div>

+ 25 - 10
app/assets/javascripts/app/views/password/reset_change.jst.eco

@@ -1,12 +1,27 @@
 <div class="fullHeight vertical center justified reset_password fit">
-  <div class="hero-unit">
-    <h2><%- @T('Choose your new password.') %></h2>
-    <form class="js-passwordForm">
-      <div class="js-password"></div>
-      <div class="form-controls">
-        <a class="btn btn--text btn--subtle js-cancel" href="#/"><%- @T('Cancel & Go Back') %></a>
-        <button class="btn btn--primary js-submit align-right"><%- @T('Submit') %></button>
-      </div>
-    </form>
+  <div class="fullscreen-center">
+    <div class="hero-unit">
+      <h2><%- @T('Choose your new password.') %></h2>
+      <form class="js-passwordForm">
+        <div class="js-password"></div>
+        <div class="form-controls">
+          <a class="btn btn--text btn--subtle js-cancel" href="#/"><%- @T('Cancel & Go Back') %></a>
+          <button class="btn btn--primary js-submit align-right"><%- @T('Submit') %></button>
+        </div>
+      </form>
+    </div>
+  <% if @public_links: %>
+    <p>
+      <% for link, link_index in @public_links: %>
+        <% if link_index > 0: %> | <% end %>
+        <a href="<%= link.link %>" title="<% if link.description: %><%= link.description %><% else: %><%= link.title %><% end %>"<% if link.new_tab: %> target="_blank"<% end %>><%= link.title %></a>
+      <% end %>
+    </p>
+  <% end %>
   </div>
-</div>
+  <div class="poweredBy">
+    <a href="https://zammad.org" target="_blank"><%- @Icon('logo') %></a>
+    <%- @T('Powered by') %>
+    <a href="https://zammad.org" target="_blank"><%- @Icon('logotype', 'logotype') %></a>
+  </div>
+</div>

Some files were not shown because too many files changed in this diff