effective_datatables 4.6.2 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 160c25c1ffac1f7c4bc0047d186733f8d449c32d92a48135ceaddb05550965f6
4
- data.tar.gz: cf1f18dc6748482ff5af51e0de2d13babdfca2185fa38f819042e072b98dd375
3
+ metadata.gz: a4470fed54cce153fddf79984ca733cfe00c3232cff43cce5b20d998b18a2f6b
4
+ data.tar.gz: 9357498f73ab31c491e28f09e9c6d4619c8960f26764210f04fbe700fa322744
5
5
  SHA512:
6
- metadata.gz: 7562d2915db7e4b575d92d249334fe243086989551ad783faff17815388095ac11adc321e349dd94b7ee027a4e2a7c3103744b201fab2f898989a180bc455bcc
7
- data.tar.gz: f55ea42ec961870daba197a13ef6ead1bac0bc5787204a4468f663efaa1bb5953eb5b5c94c1b76e29d47e4583e142db0ffeb3f924d85a5ebb36d0ec15feaed25
6
+ metadata.gz: 96329fe58fe84c6594d99048be257d38645f78fa88eeac7a55f712383014295075cd40e2ab38cfbdb592d34e76c9466a98689511b09e49205a5e5fdf442f1409
7
+ data.tar.gz: d5db73e577df3a97abfe8eff01c81699f65617652b2d2ecf1e712e0e185c908d0d76bf293993020e98bf89f9faf32b9ed318de52551d9ec702df98f2f3b5d750
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2018 Code and Effect Inc.
1
+ Copyright 2019 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -348,7 +348,7 @@ When initialized with a Hash, that hash is available throughout the entire datat
348
348
 
349
349
  You can call the attributes from within the datatable as `attributes` or within a partial/view as `@datatable.attributes`.
350
350
 
351
- These attributes are serialized and stored in an encrypted cookie. Objects won't work. Keep it simple.
351
+ These attributes are serialized and stored in an encrypted data attribute. Objects won't work. Keep it simple.
352
352
 
353
353
  Attributes cannot be changed by search, filter, or state in any way. They're guaranteed to be the same as when first initialized.
354
354
 
@@ -60,7 +60,7 @@ initializeDataTables = (target) ->
60
60
  $table = $(api.table().node())
61
61
  $form = $(".effective-datatables-filters[aria-controls='#{$table.attr('id')}']").first()
62
62
 
63
- params['cookie'] = $table.data('cookie')
63
+ params['attributes'] = $table.data('attributes')
64
64
  params['authenticity_token'] = $table.data('authenticity-token')
65
65
 
66
66
  if $form.length > 0
@@ -8,7 +8,7 @@ $(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-actions', (e, xhr, s
8
8
 
9
9
  return true if ('' + $action.data('inline')) == 'false'
10
10
 
11
- $params = $.param({_datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie'), _datatable_action: true })
11
+ $params = $.param({_datatable_id: $table.attr('id'), _datatable_attributes: $table.data('attributes'), _datatable_action: true })
12
12
  settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
13
13
 
14
14
  if $action.closest('.effective-datatables-inline-row,table.dataTable').hasClass('effective-datatables-inline-row')
@@ -60,7 +60,7 @@ $(document).on 'ajax:error', '.dataTables_wrapper', (event) ->
60
60
  $(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-inline-form', (e, xhr, settings) ->
61
61
  $table = $(e.target).closest('table')
62
62
 
63
- $params = $.param({_datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie') })
63
+ $params = $.param({_datatable_id: $table.attr('id'), _datatable_attributes: $table.data('attributes') })
64
64
  settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
65
65
 
66
66
  true
@@ -8,7 +8,7 @@ reorder = (event, diff, edit) ->
8
8
  return unless oldNode? && newNode?
9
9
 
10
10
  url = @context[0].ajax.url.replace('.json', '/reorder.json')
11
- data = {'reorder[id]': oldNode.data('reorder-resource'), 'reorder[old]': oldNode.val(), 'reorder[new]': newNode.val(), _datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie') }
11
+ data = {'reorder[id]': oldNode.data('reorder-resource'), 'reorder[old]': oldNode.val(), 'reorder[new]': newNode.val(), attributes: $table.data('attributes') }
12
12
 
13
13
  @context[0].rowreorder.c.enable = false
14
14
 
@@ -5,7 +5,7 @@ module Effective
5
5
  # This will respond to both a GET and a POST
6
6
  def show
7
7
  begin
8
- @datatable = EffectiveDatatables.find(params[:id])
8
+ @datatable = EffectiveDatatables.find(params[:id], params[:attributes])
9
9
  @datatable.view = view_context
10
10
 
11
11
  EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
@@ -22,7 +22,7 @@ module Effective
22
22
 
23
23
  def reorder
24
24
  begin
25
- @datatable = EffectiveDatatables.find(params[:id])
25
+ @datatable = EffectiveDatatables.find(params[:id], params[:attributes])
26
26
  @datatable.view = view_context
27
27
 
28
28
  EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
@@ -40,10 +40,10 @@ module EffectiveDatatablesHelper
40
40
  id: datatable.to_param,
41
41
  class: html_class,
42
42
  data: {
43
+ 'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
43
44
  'authenticity-token' => form_authenticity_token,
44
45
  'bulk-actions' => datatable_bulk_actions(datatable),
45
46
  'columns' => datatable_columns(datatable),
46
- 'cookie' => datatable.cookie_key,
47
47
  'display-length' => datatable.display_length,
48
48
  'display-order' => datatable_display_order(datatable),
49
49
  'display-records' => datatable.to_json[:recordsFiltered],
@@ -93,14 +93,14 @@ module EffectiveDatatablesHelper
93
93
  end
94
94
 
95
95
  def inline_datatable?
96
- params[:_datatable_id].present?
96
+ params[:_datatable_id].present? && params[:_datatable_attributes].present?
97
97
  end
98
98
 
99
99
  def inline_datatable
100
100
  return nil unless inline_datatable?
101
101
  return @_inline_datatable if @_inline_datatable
102
102
 
103
- datatable = EffectiveDatatables.find(params[:_datatable_id])
103
+ datatable = EffectiveDatatables.find(params[:_datatable_id], params[:_datatable_attributes])
104
104
  datatable.view = self
105
105
 
106
106
  EffectiveDatatables.authorize!(self, :index, datatable.collection_class)
@@ -31,10 +31,10 @@ module Effective
31
31
  include Effective::EffectiveDatatable::Resource
32
32
  include Effective::EffectiveDatatable::State
33
33
 
34
- def initialize(view = nil, attributes = {})
34
+ def initialize(view = nil, attributes = nil)
35
35
  (attributes = view; view = nil) if view.kind_of?(Hash)
36
36
 
37
- @attributes = initial_attributes(attributes)
37
+ @attributes = (attributes || {})
38
38
  @state = initial_state
39
39
 
40
40
  @_aggregates = {}
@@ -45,6 +45,7 @@ module Effective
45
45
  @_form = {}
46
46
  @_scopes = {}
47
47
 
48
+ raise 'expected a hash of arguments' unless @attributes.kind_of?(Hash)
48
49
  raise 'collection is defined as a method. Please use the collection do ... end syntax.' unless collection.nil?
49
50
  self.view = view if view
50
51
  end
@@ -54,14 +55,14 @@ module Effective
54
55
  @view = (view.respond_to?(:view_context) ? view.view_context : view)
55
56
  raise 'expected view to respond to params' unless @view.respond_to?(:params)
56
57
 
57
- load_cookie!
58
- assert_cookie!
58
+ assert_attributes!
59
59
  load_attributes!
60
60
 
61
61
  # We need early access to filter and scope, to define defaults from the model first
62
- # This means filters do knows about attributes but not about columns.
62
+ # This means filters do know about attributes but not about columns.
63
63
  initialize_filters if respond_to?(:initialize_filters)
64
64
  load_filters!
65
+
65
66
  load_state!
66
67
 
67
68
  # Bulk actions called first so it can add the bulk_actions_col first
@@ -147,7 +148,7 @@ module Effective
147
148
  end
148
149
 
149
150
  def to_param
150
- @to_param ||= "#{self.class.name.underscore.parameterize}-#{cookie_param}"
151
+ @to_param ||= "#{self.class.name.underscore.parameterize}-#{[self.class, attributes].hash.abs.to_s.last(12)}"
151
152
  end
152
153
 
153
154
  def columns
@@ -4,17 +4,14 @@ module Effective
4
4
 
5
5
  private
6
6
 
7
- def initial_attributes(args)
8
- raise "#{self.class.name}.new() expected Hash like arguments" unless args.kind_of?(Hash)
9
- args
7
+ def assert_attributes!
8
+ if datatables_ajax_request? || datatables_inline_request?
9
+ raise 'expected attributes to be present' unless attributes.present?
10
+ end
10
11
  end
11
12
 
12
13
  def load_attributes!
13
- if datatables_ajax_request? || datatables_inline_request?
14
- @attributes = cookie.delete(:attributes)
15
- else
16
- @attributes[:_n] ||= view.controller_path.split('/')[0...-1].join('/').presence
17
- end
14
+ @attributes[:_n] ||= view.controller_path.split('/')[0...-1].join('/').presence
18
15
  end
19
16
 
20
17
  end
@@ -6,39 +6,21 @@ module Effective
6
6
  @cookie
7
7
  end
8
8
 
9
- def cookie_key
10
- @cookie_key ||= (
11
- if datatables_ajax_request?
12
- view.params[:cookie]
13
- elsif datatables_inline_request?
14
- view.params[:_datatable_cookie]
15
- else
16
- cookie_param
17
- end
18
- )
19
- end
20
-
21
- # All possible dt cookie keys. Used to make sure the datatable has a cookie set for this session.
22
- def cookie_keys
23
- @cookie_keys ||= Array(@dt_cookie).compact.map(&:first)
24
- end
25
-
26
- def cookie_param
27
- [self.class, attributes].hash.abs.to_s.last(12) # Not guaranteed to be 12 long
28
- end
29
-
30
9
  private
31
10
 
32
11
  def load_cookie!
12
+ return unless EffectiveDatatables.save_state
13
+
33
14
  @dt_cookie = view.cookies.signed['_effective_dt']
34
15
 
35
16
  # Load global datatables cookie
36
17
  if @dt_cookie.present?
18
+
37
19
  @dt_cookie = Marshal.load(Base64.decode64(@dt_cookie))
38
20
  raise 'invalid datatables cookie' unless @dt_cookie.kind_of?(Array)
39
21
 
40
22
  # Assign individual cookie
41
- index = @dt_cookie.rindex { |key, _| key == cookie_key }
23
+ index = @dt_cookie.rindex { |key, _| key == to_param }
42
24
  @cookie = @dt_cookie.delete_at(index) if index
43
25
  end
44
26
 
@@ -46,18 +28,14 @@ module Effective
46
28
  if @cookie.kind_of?(Array)
47
29
  @cookie = initial_state.keys.zip(@cookie.second).to_h
48
30
  end
49
- end
50
31
 
51
- def assert_cookie!
52
- if datatables_ajax_request? || datatables_inline_request?
53
- raise 'expected cookie to be present' unless cookie
54
- raise 'expected attributes cookie to be present' unless cookie[:attributes]
55
- end
56
32
  end
57
33
 
58
34
  def save_cookie!
35
+ return unless EffectiveDatatables.save_state
36
+
59
37
  @dt_cookie ||= []
60
- @dt_cookie << [cookie_key, cookie_payload]
38
+ @dt_cookie << [to_param, cookie_payload]
61
39
 
62
40
  while @dt_cookie.to_s.size > EffectiveDatatables.cookie_max_size.to_i
63
41
  @dt_cookie.shift((@dt_cookie.length / 3) + 1)
@@ -72,7 +50,7 @@ module Effective
72
50
  end
73
51
 
74
52
  def cookie_payload
75
- payload = state.except(:attributes, :visible)
53
+ payload = state.except(:visible)
76
54
 
77
55
  # Turn visible into a bitmask. This is undone in load_columns!
78
56
  payload[:vismask] = (
@@ -81,8 +59,7 @@ module Effective
81
59
  end
82
60
  )
83
61
 
84
- # Just store the values
85
- [attributes] + payload.values
62
+ payload.values # Just store the values
86
63
  end
87
64
 
88
65
  end
@@ -7,17 +7,13 @@ module Effective
7
7
  def datatables_ajax_request?
8
8
  return @_datatables_ajax_request unless @_datatables_ajax_request.nil?
9
9
 
10
- @_datatables_ajax_request = (view.present? && view.params.key?(:draw) && view.params.key?(:columns) && view.params.key?(:cookie))
10
+ @_datatables_ajax_request = (view.present? && view.params.key?(:draw) && view.params.key?(:columns))
11
11
  end
12
12
 
13
13
  def datatables_inline_request?
14
14
  return @_datatables_inline_request unless @_datatables_inline_request.nil?
15
15
 
16
- @_datatables_inline_request = (
17
- view &&
18
- view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1] &&
19
- cookie_keys.include?(view.params[:_datatable_cookie])
20
- )
16
+ @_datatables_inline_request = (view.present? && view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1])
21
17
  end
22
18
 
23
19
  def params
@@ -55,7 +55,6 @@ module Effective
55
55
  # This is called first. Our initial state is set.
56
56
  def initial_state
57
57
  {
58
- attributes: {},
59
58
  filter: {},
60
59
  length: nil,
61
60
  order_name: nil,
@@ -89,17 +88,17 @@ module Effective
89
88
 
90
89
  def load_state!
91
90
  if datatables_ajax_request?
91
+ load_cookie! # but not state.
92
92
  load_filter_params!
93
93
  load_ajax_state!
94
94
  elsif datatables_inline_request?
95
- load_cookie_state!
96
- elsif cookie.present? && cookie[:params] == params.length && EffectiveDatatables.save_state
97
- load_cookie_state!
95
+ load_filter_params!
98
96
  else
99
- # Nothing to do for default state
97
+ load_cookie!
98
+ load_cookie_state! if cookie.present? && cookie[:params] == cookie_state_params
99
+ load_filter_params!
100
100
  end
101
-
102
- load_filter_params! unless datatables_ajax_request?
101
+
103
102
  fill_empty_filters!
104
103
  end
105
104
 
@@ -134,7 +133,7 @@ module Effective
134
133
  state[:filter][name] = parse_filter_value(_filters[name], value)
135
134
  end
136
135
 
137
- state[:params] = cookie[:params]
136
+ state[:params] = cookie[:params] if cookie.present?
138
137
  end
139
138
 
140
139
  def load_cookie_state!
@@ -187,7 +186,7 @@ module Effective
187
186
 
188
187
  unless datatables_ajax_request?
189
188
  search_params.each { |name, value| state[:search][name] = value }
190
- state[:params] = params.length
189
+ state[:params] = cookie_state_params
191
190
  end
192
191
 
193
192
  state[:visible].delete_if { |name, _| columns.key?(name) == false }
@@ -202,6 +201,10 @@ module Effective
202
201
  Effective::Attribute.new(filter[:value]).parse(value, name: filter[:name])
203
202
  end
204
203
 
204
+ def cookie_state_params
205
+ params.hash.abs.to_s.last(12)
206
+ end
207
+
205
208
  end
206
209
  end
207
210
  end
@@ -31,8 +31,7 @@ EffectiveDatatables.setup do |config|
31
31
  # Log search/sort information to the console
32
32
  config.debug = true
33
33
 
34
- # If a user has previously visited this page and is returning, use the cookie to restore last session
35
- # Irregardless of this setting, effective_datatables still uses a cookie to function
34
+ # Use a cookie to save and restore state from previous page visits.
36
35
  config.save_state = true
37
36
 
38
37
  # Configure the _effective_dt cookie.
@@ -42,11 +42,12 @@ module EffectiveDatatables
42
42
  raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
43
43
  end
44
44
 
45
- def self.find(id)
45
+ def self.find(id, attributes = nil)
46
46
  id = id.to_s.gsub(/-\d+\z/, '').gsub('-', '/')
47
47
  klass = (id.classify.safe_constantize || id.classify.pluralize.safe_constantize)
48
+ attributes = decrypt(attributes) || {}
48
49
 
49
- klass.try(:new) || raise('unable to find datatable')
50
+ klass.try(:new, **attributes) || raise('unable to find datatable')
50
51
  end
51
52
 
52
53
  # Locale is coming from view. I think it can be dynamic.
@@ -62,4 +63,23 @@ module EffectiveDatatables
62
63
  end
63
64
  end
64
65
 
66
+ def self.encrypt(attributes)
67
+ payload = message_encrypter.encrypt_and_sign(attributes)
68
+ end
69
+
70
+ def self.decrypt(payload)
71
+ return unless payload.present?
72
+ return payload if payload.kind_of?(Hash)
73
+
74
+ attributes = message_encrypter.decrypt_and_verify(payload)
75
+
76
+ raise 'invalid decoded inline payload' unless attributes.kind_of?(Hash)
77
+
78
+ attributes
79
+ end
80
+
81
+ def self.message_encrypter
82
+ ActiveSupport::MessageEncryptor.new(Rails.application.secret_key_base.to_s.first(32))
83
+ end
84
+
65
85
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '4.6.2'.freeze
2
+ VERSION = '4.7.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_datatables
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.2
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-31 00:00:00.000000000 Z
11
+ date: 2019-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails