tina4ruby 3.10.83 → 3.10.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/tina4/auth.rb +13 -13
- data/lib/tina4/middleware.rb +3 -5
- data/lib/tina4/migration.rb +17 -0
- data/lib/tina4/orm.rb +48 -25
- data/lib/tina4/queue.rb +10 -10
- data/lib/tina4/queue_backends/lite_backend.rb +23 -19
- data/lib/tina4/rack_app.rb +2 -3
- data/lib/tina4/session.rb +5 -4
- data/lib/tina4/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e5521375e695d48e70b9f86d6a5c7abb62f9e887ee02ab975308bd51a99ee91
|
|
4
|
+
data.tar.gz: fd6c0fb85f91def5fbae4996752c70c36f184cfbec1f61cbc4d3949a8109a4fc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d4a4d7db8e8fa3b87df07f19ab708ef9a3aebc00d40a5280adf7637869ef9ea40a4b1afce22aa3fd83bfdc6de073fb3eaa34c4842bdc5e6dedf2947758c6cd9
|
|
7
|
+
data.tar.gz: fdb5d4fd739f8926f8ec6cbed5d12691219d8938217bc7f3234fa8e1d166487ed8f12095c45e5dd128a3782412b1ef0685d85901e7972db05a0565e48baea4d6
|
data/lib/tina4/auth.rb
CHANGED
|
@@ -107,19 +107,19 @@ module Tina4
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
|
|
110
|
-
def valid_token(token)
|
|
110
|
+
def valid_token(token) # -> bool
|
|
111
111
|
if use_hmac?
|
|
112
|
-
hmac_decode(token, hmac_secret)
|
|
112
|
+
!hmac_decode(token, hmac_secret).nil?
|
|
113
113
|
else
|
|
114
114
|
ensure_keys
|
|
115
115
|
require "jwt"
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
JWT.decode(token, public_key, true, algorithm: "RS256")
|
|
117
|
+
true
|
|
118
118
|
end
|
|
119
119
|
rescue JWT::ExpiredSignature
|
|
120
|
-
|
|
120
|
+
false
|
|
121
121
|
rescue JWT::DecodeError
|
|
122
|
-
|
|
122
|
+
false
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def valid_token_detail(token)
|
|
@@ -174,9 +174,10 @@ module Tina4
|
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
def refresh_token(token, expires_in: 60)
|
|
177
|
-
|
|
178
|
-
return nil unless payload
|
|
177
|
+
return nil unless valid_token(token)
|
|
179
178
|
|
|
179
|
+
payload = get_payload(token)
|
|
180
|
+
return nil unless payload
|
|
180
181
|
payload = payload.reject { |k, _| %w[iat exp nbf].include?(k) }
|
|
181
182
|
get_token(payload, expires_in: expires_in)
|
|
182
183
|
end
|
|
@@ -193,7 +194,7 @@ module Tina4
|
|
|
193
194
|
return { "api_key" => true }
|
|
194
195
|
end
|
|
195
196
|
|
|
196
|
-
valid_token(token)
|
|
197
|
+
valid_token(token) ? get_payload(token) : nil
|
|
197
198
|
end
|
|
198
199
|
|
|
199
200
|
def validate_api_key(provided, expected: nil)
|
|
@@ -227,9 +228,8 @@ module Tina4
|
|
|
227
228
|
return true
|
|
228
229
|
end
|
|
229
230
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
env["tina4.auth"] = payload
|
|
231
|
+
if valid_token(token)
|
|
232
|
+
env["tina4.auth"] = get_payload(token)
|
|
233
233
|
true
|
|
234
234
|
else
|
|
235
235
|
false
|
|
@@ -287,7 +287,7 @@ module Tina4
|
|
|
287
287
|
return true if auth_header.empty?
|
|
288
288
|
|
|
289
289
|
if auth_header =~ /\ABearer\s+(.+)\z/i
|
|
290
|
-
|
|
290
|
+
valid_token(Regexp.last_match(1))
|
|
291
291
|
else
|
|
292
292
|
false
|
|
293
293
|
end
|
data/lib/tina4/middleware.rb
CHANGED
|
@@ -307,8 +307,7 @@ module Tina4
|
|
|
307
307
|
if auth_header.start_with?("Bearer ")
|
|
308
308
|
bearer_token = auth_header[7..].strip
|
|
309
309
|
unless bearer_token.empty?
|
|
310
|
-
|
|
311
|
-
return [request, response] if payload
|
|
310
|
+
return [request, response] if Tina4::Auth.valid_token(bearer_token)
|
|
312
311
|
end
|
|
313
312
|
end
|
|
314
313
|
|
|
@@ -344,14 +343,13 @@ module Tina4
|
|
|
344
343
|
end
|
|
345
344
|
|
|
346
345
|
# Validate the token
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
if payload.nil?
|
|
346
|
+
unless Tina4::Auth.valid_token(token.to_s)
|
|
350
347
|
response.json({ error: "CSRF_INVALID", message: "Invalid or missing form token" }, 403)
|
|
351
348
|
return [request, response]
|
|
352
349
|
end
|
|
353
350
|
|
|
354
351
|
# Session binding — if token has session_id, verify it matches
|
|
352
|
+
payload = Tina4::Auth.get_payload(token.to_s) || {}
|
|
355
353
|
token_session_id = payload["session_id"]
|
|
356
354
|
if token_session_id
|
|
357
355
|
current_session_id = nil
|
data/lib/tina4/migration.rb
CHANGED
|
@@ -87,6 +87,23 @@ module Tina4
|
|
|
87
87
|
filepath
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
# Get list of applied migration records (public alias for completed_migrations)
|
|
91
|
+
def get_applied
|
|
92
|
+
completed_migrations
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Get list of pending migration filenames (public alias for pending_migrations)
|
|
96
|
+
def get_pending
|
|
97
|
+
pending_migrations.map { |f| File.basename(f) }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Get all migration files on disk, excluding .down files
|
|
101
|
+
def get_files
|
|
102
|
+
migration_files = Dir.glob(File.join(@migrations_dir, "*.sql")).reject { |f| f.end_with?(".down.sql") }
|
|
103
|
+
migration_files += Dir.glob(File.join(@migrations_dir, "*.rb"))
|
|
104
|
+
migration_files.map { |f| File.basename(f) }.sort
|
|
105
|
+
end
|
|
106
|
+
|
|
90
107
|
private
|
|
91
108
|
|
|
92
109
|
# Resolve migrations directory: prefer src/migrations, fall back to migrations/
|
data/lib/tina4/orm.rb
CHANGED
|
@@ -79,7 +79,7 @@ module Tina4
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# has_one :profile, class_name: "Profile", foreign_key: "user_id"
|
|
82
|
-
def has_one(name, class_name: nil, foreign_key: nil)
|
|
82
|
+
def has_one(name, class_name: nil, foreign_key: nil) # -> nil
|
|
83
83
|
relationship_definitions[name] = {
|
|
84
84
|
type: :has_one,
|
|
85
85
|
class_name: class_name || name.to_s.split("_").map(&:capitalize).join,
|
|
@@ -92,7 +92,7 @@ module Tina4
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
# has_many :posts, class_name: "Post", foreign_key: "user_id"
|
|
95
|
-
def has_many(name, class_name: nil, foreign_key: nil)
|
|
95
|
+
def has_many(name, class_name: nil, foreign_key: nil) # -> nil
|
|
96
96
|
relationship_definitions[name] = {
|
|
97
97
|
type: :has_many,
|
|
98
98
|
class_name: class_name || name.to_s.sub(/s$/, "").split("_").map(&:capitalize).join,
|
|
@@ -105,7 +105,7 @@ module Tina4
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
# belongs_to :user, class_name: "User", foreign_key: "user_id"
|
|
108
|
-
def belongs_to(name, class_name: nil, foreign_key: nil)
|
|
108
|
+
def belongs_to(name, class_name: nil, foreign_key: nil) # -> nil
|
|
109
109
|
relationship_definitions[name] = {
|
|
110
110
|
type: :belongs_to,
|
|
111
111
|
class_name: class_name || name.to_s.split("_").map(&:capitalize).join,
|
|
@@ -123,7 +123,7 @@ module Tina4
|
|
|
123
123
|
# results = User.query.where("active = ?", [1]).order_by("name").get
|
|
124
124
|
#
|
|
125
125
|
# @return [Tina4::QueryBuilder]
|
|
126
|
-
def query
|
|
126
|
+
def query # -> QueryBuilder
|
|
127
127
|
QueryBuilder.from(table_name, db: db)
|
|
128
128
|
end
|
|
129
129
|
|
|
@@ -136,7 +136,7 @@ module Tina4
|
|
|
136
136
|
# User.find → all records
|
|
137
137
|
#
|
|
138
138
|
# Use find_by_id(id) for single-record primary key lookup.
|
|
139
|
-
def find(filter = {}, limit: 100, offset: 0, order_by: nil, include: nil, **extra_filter)
|
|
139
|
+
def find(filter = {}, limit: 100, offset: 0, order_by: nil, include: nil, **extra_filter) # -> list[Self]
|
|
140
140
|
# Integer or string-digit argument → primary key lookup (returns single record or nil)
|
|
141
141
|
return find_by_id(filter) if filter.is_a?(Integer)
|
|
142
142
|
|
|
@@ -243,7 +243,7 @@ module Tina4
|
|
|
243
243
|
end
|
|
244
244
|
end
|
|
245
245
|
|
|
246
|
-
def where(conditions, params = [], include: nil)
|
|
246
|
+
def where(conditions, params = [], include: nil) # -> list[Self]
|
|
247
247
|
sql = "SELECT * FROM #{table_name}"
|
|
248
248
|
if soft_delete
|
|
249
249
|
sql += " WHERE (#{soft_delete_field} IS NULL OR #{soft_delete_field} = 0) AND (#{conditions})"
|
|
@@ -256,7 +256,7 @@ module Tina4
|
|
|
256
256
|
instances
|
|
257
257
|
end
|
|
258
258
|
|
|
259
|
-
def all(limit: nil, offset: nil, order_by: nil, include: nil)
|
|
259
|
+
def all(limit: nil, offset: nil, order_by: nil, include: nil) # -> list[Self]
|
|
260
260
|
sql = "SELECT * FROM #{table_name}"
|
|
261
261
|
if soft_delete
|
|
262
262
|
sql += " WHERE #{soft_delete_field} IS NULL OR #{soft_delete_field} = 0"
|
|
@@ -268,19 +268,19 @@ module Tina4
|
|
|
268
268
|
instances
|
|
269
269
|
end
|
|
270
270
|
|
|
271
|
-
def select(sql, params = [], limit: nil, offset: nil, include: nil)
|
|
271
|
+
def select(sql, params = [], limit: nil, offset: nil, include: nil) # -> list[Self]
|
|
272
272
|
results = db.fetch(sql, params, limit: limit, offset: offset)
|
|
273
273
|
instances = results.map { |row| from_hash(row) }
|
|
274
274
|
eager_load(instances, include) if include
|
|
275
275
|
instances
|
|
276
276
|
end
|
|
277
277
|
|
|
278
|
-
def select_one(sql, params = [], include: nil)
|
|
278
|
+
def select_one(sql, params = [], include: nil) # -> Self | nil
|
|
279
279
|
results = select(sql, params, limit: 1, include: include)
|
|
280
280
|
results.first
|
|
281
281
|
end
|
|
282
282
|
|
|
283
|
-
def count(conditions = nil, params = [])
|
|
283
|
+
def count(conditions = nil, params = []) # -> int
|
|
284
284
|
sql = "SELECT COUNT(*) as cnt FROM #{table_name}"
|
|
285
285
|
where_parts = []
|
|
286
286
|
if soft_delete
|
|
@@ -292,25 +292,48 @@ module Tina4
|
|
|
292
292
|
result[:cnt].to_i
|
|
293
293
|
end
|
|
294
294
|
|
|
295
|
-
def create(attributes = {})
|
|
295
|
+
def create(attributes = {}) # -> Self
|
|
296
296
|
instance = new(attributes)
|
|
297
297
|
instance.save
|
|
298
298
|
instance
|
|
299
299
|
end
|
|
300
300
|
|
|
301
|
-
def find_or_fail(id)
|
|
301
|
+
def find_or_fail(id) # -> Self
|
|
302
302
|
result = find(id)
|
|
303
303
|
raise "#{name} with #{primary_key_field || :id}=#{id} not found" if result.nil?
|
|
304
304
|
result
|
|
305
305
|
end
|
|
306
306
|
|
|
307
|
-
|
|
307
|
+
# Return true if a record with the given primary key exists.
|
|
308
|
+
def exists(pk_value) # -> bool
|
|
309
|
+
find(pk_value) != nil
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# SQL query with in-memory result caching.
|
|
313
|
+
# Results are cached by (class, sql, params, limit, offset) for +ttl+ seconds.
|
|
314
|
+
def cached(sql, params = [], ttl: 60, limit: 20, offset: 0, include: nil) # -> list[Self]
|
|
315
|
+
@_query_cache ||= Tina4::QueryCache.new(default_ttl: ttl, max_size: 500)
|
|
316
|
+
cache_key = Tina4::QueryCache.query_key("#{name}:#{sql}", params + [limit, offset])
|
|
317
|
+
hit = @_query_cache.get(cache_key)
|
|
318
|
+
return hit unless hit.nil?
|
|
319
|
+
|
|
320
|
+
results = select(sql, params, limit: limit, offset: offset, include: include)
|
|
321
|
+
@_query_cache.set(cache_key, results, ttl: ttl, tags: [name])
|
|
322
|
+
results
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Clear all cached query results for this model.
|
|
326
|
+
def clear_cache # -> nil
|
|
327
|
+
@_query_cache&.clear_tag(name)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def with_trashed(conditions = "1=1", params = [], limit: 20, offset: 0) # -> list[Self]
|
|
308
331
|
sql = "SELECT * FROM #{table_name} WHERE #{conditions}"
|
|
309
332
|
results = db.fetch(sql, params, limit: limit, offset: offset)
|
|
310
333
|
results.map { |row| from_hash(row) }
|
|
311
334
|
end
|
|
312
335
|
|
|
313
|
-
def create_table
|
|
336
|
+
def create_table # -> bool
|
|
314
337
|
return true if db.table_exists?(table_name)
|
|
315
338
|
|
|
316
339
|
type_map = {
|
|
@@ -351,7 +374,7 @@ module Tina4
|
|
|
351
374
|
true
|
|
352
375
|
end
|
|
353
376
|
|
|
354
|
-
def scope(name, filter_sql, params = [])
|
|
377
|
+
def scope(name, filter_sql, params = []) # -> nil
|
|
355
378
|
define_singleton_method(name) do |limit: 20, offset: 0|
|
|
356
379
|
where(filter_sql, params)
|
|
357
380
|
end
|
|
@@ -371,7 +394,7 @@ module Tina4
|
|
|
371
394
|
end
|
|
372
395
|
|
|
373
396
|
# Find a single record by primary key. Returns instance or nil.
|
|
374
|
-
def find_by_id(id)
|
|
397
|
+
def find_by_id(id) # -> Self | nil
|
|
375
398
|
pk = primary_key_field || :id
|
|
376
399
|
sql = "SELECT * FROM #{table_name} WHERE #{pk} = ?"
|
|
377
400
|
if soft_delete
|
|
@@ -416,7 +439,7 @@ module Tina4
|
|
|
416
439
|
end
|
|
417
440
|
end
|
|
418
441
|
|
|
419
|
-
def save
|
|
442
|
+
def save # -> Self | bool
|
|
420
443
|
@errors = []
|
|
421
444
|
@relationship_cache = {} # Clear relationship cache on save
|
|
422
445
|
validate_fields
|
|
@@ -448,7 +471,7 @@ module Tina4
|
|
|
448
471
|
false
|
|
449
472
|
end
|
|
450
473
|
|
|
451
|
-
def delete
|
|
474
|
+
def delete # -> bool
|
|
452
475
|
pk = self.class.primary_key_field || :id
|
|
453
476
|
pk_value = __send__(pk)
|
|
454
477
|
return false unless pk_value
|
|
@@ -468,7 +491,7 @@ module Tina4
|
|
|
468
491
|
true
|
|
469
492
|
end
|
|
470
493
|
|
|
471
|
-
def force_delete
|
|
494
|
+
def force_delete # -> bool
|
|
472
495
|
pk = self.class.primary_key_field || :id
|
|
473
496
|
pk_value = __send__(pk)
|
|
474
497
|
raise "Cannot delete: no primary key value" unless pk_value
|
|
@@ -480,7 +503,7 @@ module Tina4
|
|
|
480
503
|
true
|
|
481
504
|
end
|
|
482
505
|
|
|
483
|
-
def restore
|
|
506
|
+
def restore # -> bool
|
|
484
507
|
raise "Model does not support soft delete" unless self.class.soft_delete
|
|
485
508
|
|
|
486
509
|
pk = self.class.primary_key_field || :id
|
|
@@ -498,7 +521,7 @@ module Tina4
|
|
|
498
521
|
true
|
|
499
522
|
end
|
|
500
523
|
|
|
501
|
-
def validate
|
|
524
|
+
def validate # -> list[str]
|
|
502
525
|
errors = []
|
|
503
526
|
self.class.field_definitions.each do |name, opts|
|
|
504
527
|
value = __send__(name)
|
|
@@ -519,7 +542,7 @@ module Tina4
|
|
|
519
542
|
# orm.load("id = 1") — filter string
|
|
520
543
|
#
|
|
521
544
|
# Returns true if a record was found, false otherwise.
|
|
522
|
-
def load(filter = nil, params = [], include: nil)
|
|
545
|
+
def load(filter = nil, params = [], include: nil) # -> bool
|
|
523
546
|
@relationship_cache = {}
|
|
524
547
|
table = self.class.table_name
|
|
525
548
|
|
|
@@ -557,7 +580,7 @@ module Tina4
|
|
|
557
580
|
|
|
558
581
|
# Convert to hash using Ruby attribute names.
|
|
559
582
|
# Optionally include relationships via the include keyword.
|
|
560
|
-
def to_h(include: nil)
|
|
583
|
+
def to_h(include: nil) # -> dict
|
|
561
584
|
hash = {}
|
|
562
585
|
self.class.field_definitions.each_key do |name|
|
|
563
586
|
hash[name] = __send__(name)
|
|
@@ -594,13 +617,13 @@ module Tina4
|
|
|
594
617
|
alias to_assoc to_h
|
|
595
618
|
alias to_object to_h
|
|
596
619
|
|
|
597
|
-
def to_array
|
|
620
|
+
def to_array # -> list
|
|
598
621
|
to_h.values
|
|
599
622
|
end
|
|
600
623
|
|
|
601
624
|
alias to_list to_array
|
|
602
625
|
|
|
603
|
-
def to_json(include: nil, **_args)
|
|
626
|
+
def to_json(include: nil, **_args) # -> str
|
|
604
627
|
JSON.generate(to_h(include: include))
|
|
605
628
|
end
|
|
606
629
|
|
data/lib/tina4/queue.rb
CHANGED
|
@@ -36,49 +36,49 @@ module Tina4
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# Pop the next available job. Returns Job or nil.
|
|
39
|
-
def pop
|
|
39
|
+
def pop # -> Job|None
|
|
40
40
|
@backend.dequeue(@topic)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
# Clear all pending jobs from this queue's topic. Returns count removed.
|
|
44
|
-
def clear
|
|
44
|
+
def clear # -> int
|
|
45
45
|
return 0 unless @backend.respond_to?(:clear)
|
|
46
46
|
@backend.clear(@topic)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Get jobs that failed but are still eligible for retry (under max_retries).
|
|
50
|
-
def failed
|
|
50
|
+
def failed # -> list[dict]
|
|
51
51
|
return [] unless @backend.respond_to?(:failed)
|
|
52
52
|
@backend.failed(@topic, max_retries: @max_retries)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
# Retry
|
|
56
|
-
def retry(
|
|
55
|
+
# Retry failed jobs on this queue's topic. Returns true if re-queued.
|
|
56
|
+
def retry(delay_seconds = 0) # -> bool
|
|
57
57
|
return false unless @backend.respond_to?(:retry_job)
|
|
58
|
-
@backend.retry_job(@topic,
|
|
58
|
+
@backend.retry_job(@topic, delay_seconds: delay_seconds)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
# Get dead letter jobs — messages that exceeded max retries.
|
|
62
|
-
def dead_letters
|
|
62
|
+
def dead_letters # -> list[dict]
|
|
63
63
|
return [] unless @backend.respond_to?(:dead_letters)
|
|
64
64
|
@backend.dead_letters(@topic, max_retries: @max_retries)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# Delete messages by status (completed, failed, dead).
|
|
68
|
-
def purge(status)
|
|
68
|
+
def purge(status) # -> int
|
|
69
69
|
return 0 unless @backend.respond_to?(:purge)
|
|
70
70
|
@backend.purge(@topic, status)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
# Re-queue failed messages (under max_retries) back to pending.
|
|
74
74
|
# Returns the number of jobs re-queued.
|
|
75
|
-
def retry_failed
|
|
75
|
+
def retry_failed # -> int
|
|
76
76
|
return 0 unless @backend.respond_to?(:retry_failed)
|
|
77
77
|
@backend.retry_failed(@topic, max_retries: @max_retries)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
# Produce a message onto a topic. Convenience wrapper around push().
|
|
81
|
-
def produce(topic, payload, priority
|
|
81
|
+
def produce(topic, payload, priority = 0)
|
|
82
82
|
message = Job.new(topic: topic, payload: payload, priority: priority)
|
|
83
83
|
@backend.enqueue(message)
|
|
84
84
|
message
|
|
@@ -218,28 +218,32 @@ module Tina4
|
|
|
218
218
|
jobs
|
|
219
219
|
end
|
|
220
220
|
|
|
221
|
-
# Retry
|
|
222
|
-
def retry_job(topic,
|
|
221
|
+
# Retry all dead letter jobs for this topic. Returns true if any were re-queued.
|
|
222
|
+
def retry_job(topic, delay_seconds: 0)
|
|
223
223
|
return false unless Dir.exist?(@dead_letter_dir)
|
|
224
|
-
file = File.join(@dead_letter_dir, "#{job_id}.json")
|
|
225
|
-
return false unless File.exist?(file)
|
|
226
|
-
|
|
227
|
-
data = JSON.parse(File.read(file))
|
|
228
|
-
return false unless data["topic"] == topic.to_s
|
|
229
224
|
|
|
230
225
|
available_at = delay_seconds > 0 ? Time.now + delay_seconds : nil
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
226
|
+
count = 0
|
|
227
|
+
|
|
228
|
+
Dir.glob(File.join(@dead_letter_dir, "*.json")).each do |file|
|
|
229
|
+
data = JSON.parse(File.read(file))
|
|
230
|
+
next unless data["topic"] == topic.to_s
|
|
231
|
+
|
|
232
|
+
msg = Tina4::Job.new(
|
|
233
|
+
topic: data["topic"],
|
|
234
|
+
payload: data["payload"],
|
|
235
|
+
id: data["id"],
|
|
236
|
+
attempts: (data["attempts"] || 0) + 1,
|
|
237
|
+
available_at: available_at
|
|
238
|
+
)
|
|
239
|
+
enqueue(msg)
|
|
240
|
+
File.delete(file)
|
|
241
|
+
count += 1
|
|
242
|
+
rescue JSON::ParserError
|
|
243
|
+
next
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
count > 0
|
|
243
247
|
end
|
|
244
248
|
|
|
245
249
|
private
|
data/lib/tina4/rack_app.rb
CHANGED
|
@@ -176,11 +176,10 @@ module Tina4
|
|
|
176
176
|
if api_key && !api_key.empty? && token == api_key
|
|
177
177
|
env["tina4.auth_payload"] = { "api_key" => true }
|
|
178
178
|
elsif token
|
|
179
|
-
|
|
180
|
-
unless payload
|
|
179
|
+
unless Tina4::Auth.valid_token(token)
|
|
181
180
|
return [401, { "content-type" => "application/json" }, [JSON.generate({ error: "Unauthorized" })]]
|
|
182
181
|
end
|
|
183
|
-
env["tina4.auth_payload"] =
|
|
182
|
+
env["tina4.auth_payload"] = Tina4::Auth.get_payload(token)
|
|
184
183
|
else
|
|
185
184
|
return [401, { "content-type" => "application/json" }, [JSON.generate({ error: "Unauthorized" })]]
|
|
186
185
|
end
|
data/lib/tina4/session.rb
CHANGED
|
@@ -114,9 +114,10 @@ module Tina4
|
|
|
114
114
|
@handler.gc(max_age) if @handler.respond_to?(:gc)
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
-
def cookie_header
|
|
117
|
+
def cookie_header(cookie_name = nil)
|
|
118
|
+
name = cookie_name || @options[:cookie_name]
|
|
118
119
|
samesite = ENV["TINA4_SESSION_SAMESITE"] || "Lax"
|
|
119
|
-
"#{
|
|
120
|
+
"#{name}=#{@id}; Path=/; HttpOnly; SameSite=#{samesite}; Max-Age=#{@options[:max_age]}"
|
|
120
121
|
end
|
|
121
122
|
|
|
122
123
|
private
|
|
@@ -223,9 +224,9 @@ module Tina4
|
|
|
223
224
|
@session.gc(max_age)
|
|
224
225
|
end
|
|
225
226
|
|
|
226
|
-
def cookie_header
|
|
227
|
+
def cookie_header(cookie_name = nil)
|
|
227
228
|
ensure_loaded
|
|
228
|
-
@session.cookie_header
|
|
229
|
+
@session.cookie_header(cookie_name)
|
|
229
230
|
end
|
|
230
231
|
|
|
231
232
|
def to_hash
|
data/lib/tina4/version.rb
CHANGED