ioredis-toolkit 0.0.11 → 0.0.12
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.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/scripts/cleanup-index.lua +0 -4
- package/src/scripts/conditional-update.lua +0 -21
- package/src/scripts/consume-session.lua +0 -21
- package/src/scripts/create-session.lua +0 -28
- package/src/scripts/delete.lua +0 -2
- package/src/scripts/destroy-user.lua +0 -13
- package/src/scripts/enforce-limit.lua +0 -17
- package/src/scripts/revoke-session.lua +0 -13
- package/src/scripts/rotate.lua +0 -24
- package/src/scripts/touch-session.lua +0 -28
- package/src/scripts/update-session.lua +0 -18
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
-- Reference copy only. This duplicates update-session.lua: both must mirror the
|
|
2
|
-
-- authoritative script actually executed at runtime, SCRIPT_SOURCES.update_session
|
|
3
|
-
-- in src/session/script-sources.ts. Do not use this script directly.
|
|
4
|
-
-- KEYS[1] session key
|
|
5
|
-
-- ARGV[1] expected version
|
|
6
|
-
-- ARGV[2] now
|
|
7
|
-
-- ARGV[3] serialized replacement
|
|
8
|
-
local raw = redis.call('GET', KEYS[1])
|
|
9
|
-
if not raw then return {0} end
|
|
10
|
-
local ok, s = pcall(cjson.decode, raw)
|
|
11
|
-
if not ok or not s.data then return {-4} end
|
|
12
|
-
if s.data.status ~= 'active' then return {-3} end
|
|
13
|
-
if tonumber(s.data.version) ~= tonumber(ARGV[1]) then return {-2, s.data.version} end
|
|
14
|
-
local replacement = ARGV[3]
|
|
15
|
-
local ok2, parsed = pcall(cjson.decode, replacement)
|
|
16
|
-
if not ok2 or not parsed.data then return {-4} end
|
|
17
|
-
if parsed.data.userId ~= s.data.userId or parsed.data.jti ~= s.data.jti or parsed.data.id ~= s.data.id or parsed.data.createdAt ~= s.data.createdAt or parsed.data.absoluteExpiresAt ~= s.data.absoluteExpiresAt then return {-5} end
|
|
18
|
-
local ttl = tonumber(s.data.expiresAt) - tonumber(ARGV[2])
|
|
19
|
-
if ttl <= 0 then return {-1} end
|
|
20
|
-
redis.call('SET', KEYS[1], replacement, 'XX', 'EX', ttl)
|
|
21
|
-
return {1}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
-- KEYS[1] session key
|
|
2
|
-
-- ARGV[1] now epoch seconds
|
|
3
|
-
-- ARGV[2] tombstone ttl seconds
|
|
4
|
-
local raw = redis.call('GET', KEYS[1])
|
|
5
|
-
if not raw then return {0} end
|
|
6
|
-
local ok, s = pcall(cjson.decode, raw)
|
|
7
|
-
if not ok or not s.data then return {-4} end
|
|
8
|
-
local r = s.data
|
|
9
|
-
if r.status == 'consumed' then return {-1} end
|
|
10
|
-
if r.status == 'revoked' then return {-3} end
|
|
11
|
-
local now = tonumber(ARGV[1])
|
|
12
|
-
if tonumber(r.expiresAt) <= now then return {-2} end
|
|
13
|
-
if r.absoluteExpiresAt and r.absoluteExpiresAt ~= cjson.null and tonumber(r.absoluteExpiresAt) > 0 and tonumber(r.absoluteExpiresAt) <= now then return {-2} end
|
|
14
|
-
if r.idleExpiresAt and tonumber(r.idleExpiresAt) > 0 and tonumber(r.idleExpiresAt) <= now then return {-2} end
|
|
15
|
-
r.status = 'consumed'
|
|
16
|
-
r.consumedAt = now
|
|
17
|
-
r.version = tonumber(r.version) + 1
|
|
18
|
-
local ttl = tonumber(ARGV[2])
|
|
19
|
-
local encoded = cjson.encode({v=1, data=r})
|
|
20
|
-
redis.call('SET', KEYS[1], encoded, 'XX', 'EX', ttl)
|
|
21
|
-
return {1, r.userId, r.jti, r.version}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
-- Reference copy only. The authoritative script actually executed at runtime is
|
|
2
|
-
-- SCRIPT_SOURCES.create_session in src/session/script-sources.ts — keep this file in sync with it.
|
|
3
|
-
-- KEYS[1] session key
|
|
4
|
-
-- KEYS[2] user index
|
|
5
|
-
-- ARGV[1] serialized record
|
|
6
|
-
-- ARGV[2] ttl seconds
|
|
7
|
-
-- ARGV[3] createdAt score
|
|
8
|
-
-- ARGV[4] tokenHash
|
|
9
|
-
-- ARGV[5] max sessions (0 = unlimited)
|
|
10
|
-
-- ARGV[6] namespace
|
|
11
|
-
-- ARGV[7] userTag
|
|
12
|
-
local created = redis.call('SET', KEYS[1], ARGV[1], 'NX', 'EX', ARGV[2])
|
|
13
|
-
if not created then return {-1} end
|
|
14
|
-
redis.call('ZADD', KEYS[2], ARGV[3], ARGV[4])
|
|
15
|
-
if tonumber(ARGV[5]) > 0 then
|
|
16
|
-
local count = redis.call('ZCARD', KEYS[2])
|
|
17
|
-
if count > tonumber(ARGV[5]) then
|
|
18
|
-
local excess = count - tonumber(ARGV[5])
|
|
19
|
-
local old = redis.call('ZRANGE', KEYS[2], 0, excess - 1)
|
|
20
|
-
for _, evictedHash in ipairs(old) do
|
|
21
|
-
redis.call('ZREM', KEYS[2], evictedHash)
|
|
22
|
-
redis.call('DEL', ARGV[6] .. ':session:{' .. ARGV[7] .. '}:' .. evictedHash)
|
|
23
|
-
redis.call('DEL', ARGV[6] .. ':token-index:' .. evictedHash)
|
|
24
|
-
end
|
|
25
|
-
return {1, excess}
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
return {1}
|
package/src/scripts/delete.lua
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
-- Reference copy only. Not present in SCRIPT_SOURCES and not executed by the
|
|
2
|
-
-- repository at runtime (SessionRepository.revokeAll implements the equivalent
|
|
3
|
-
-- operation in TypeScript via a pipeline). Bounded helper: the application must
|
|
4
|
-
-- pass session keys to delete as KEYS, matching enforce-limit.lua's pattern.
|
|
5
|
-
-- KEYS[1] user index; KEYS[2..N] session keys corresponding to the returned members.
|
|
6
|
-
-- ARGV[1] max batch
|
|
7
|
-
local n = tonumber(ARGV[1])
|
|
8
|
-
local members = redis.call('ZRANGE', KEYS[1], 0, n - 1)
|
|
9
|
-
for i, tokenHash in ipairs(members) do
|
|
10
|
-
redis.call('ZREM', KEYS[1], tokenHash)
|
|
11
|
-
redis.call('DEL', KEYS[i + 1])
|
|
12
|
-
end
|
|
13
|
-
return members
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
-- Bounded helper. The application must pass session keys to delete as KEYS.
|
|
2
|
-
-- KEYS[1] user index; KEYS[2..N] session keys corresponding to the oldest members.
|
|
3
|
-
-- ARGV[1] max sessions; ARGV[2] number of candidate keys.
|
|
4
|
-
local max=tonumber(ARGV[1])
|
|
5
|
-
local candidateCount=tonumber(ARGV[2])
|
|
6
|
-
local count=redis.call('ZCARD', KEYS[1])
|
|
7
|
-
if max <= 0 or count <= max then return {0} end
|
|
8
|
-
local excess=math.min(count-max, candidateCount)
|
|
9
|
-
local removed=0
|
|
10
|
-
for i=1,excess do
|
|
11
|
-
local tokenHash=redis.call('ZRANGE', KEYS[1], 0, 0)[1]
|
|
12
|
-
if not tokenHash then break end
|
|
13
|
-
redis.call('ZREM', KEYS[1], tokenHash)
|
|
14
|
-
redis.call('DEL', KEYS[i+1])
|
|
15
|
-
removed=removed+1
|
|
16
|
-
end
|
|
17
|
-
return {removed}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
-- KEYS[1] session key
|
|
2
|
-
-- ARGV[1] now
|
|
3
|
-
-- ARGV[2] tombstone ttl
|
|
4
|
-
local raw = redis.call('GET', KEYS[1])
|
|
5
|
-
if not raw then return {0} end
|
|
6
|
-
local ok, s = pcall(cjson.decode, raw)
|
|
7
|
-
if not ok or not s.data then return {-4} end
|
|
8
|
-
local r=s.data
|
|
9
|
-
if r.status == 'revoked' then return {2} end
|
|
10
|
-
r.status='revoked'; r.version=tonumber(r.version)+1
|
|
11
|
-
local ttl=tonumber(ARGV[2])
|
|
12
|
-
if ttl < 1 then redis.call('DEL', KEYS[1]) else redis.call('SET', KEYS[1], cjson.encode({v=1,data=r}), 'XX', 'EX', ttl) end
|
|
13
|
-
return {1}
|
package/src/scripts/rotate.lua
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
-- Reference copy only. This duplicates consume-session.lua: both must mirror the
|
|
2
|
-
-- authoritative script actually executed at runtime, SCRIPT_SOURCES.consume_session
|
|
3
|
-
-- in src/session/script-sources.ts. Do not use this script directly.
|
|
4
|
-
-- KEYS[1] session key
|
|
5
|
-
-- ARGV[1] now epoch seconds
|
|
6
|
-
-- ARGV[2] tombstone ttl seconds
|
|
7
|
-
local raw = redis.call('GET', KEYS[1])
|
|
8
|
-
if not raw then return {0} end
|
|
9
|
-
local ok, s = pcall(cjson.decode, raw)
|
|
10
|
-
if not ok or not s.data then return {-4} end
|
|
11
|
-
local r = s.data
|
|
12
|
-
if r.status == 'consumed' then return {-1} end
|
|
13
|
-
if r.status == 'revoked' then return {-3} end
|
|
14
|
-
local now = tonumber(ARGV[1])
|
|
15
|
-
if tonumber(r.expiresAt) <= now then return {-2} end
|
|
16
|
-
if r.absoluteExpiresAt and r.absoluteExpiresAt ~= cjson.null and tonumber(r.absoluteExpiresAt) > 0 and tonumber(r.absoluteExpiresAt) <= now then return {-2} end
|
|
17
|
-
if r.idleExpiresAt and tonumber(r.idleExpiresAt) > 0 and tonumber(r.idleExpiresAt) <= now then return {-2} end
|
|
18
|
-
r.status = 'consumed'
|
|
19
|
-
r.consumedAt = now
|
|
20
|
-
r.version = tonumber(r.version) + 1
|
|
21
|
-
local ttl = tonumber(ARGV[2])
|
|
22
|
-
local encoded = cjson.encode({v=1, data=r})
|
|
23
|
-
redis.call('SET', KEYS[1], encoded, 'XX', 'EX', ttl)
|
|
24
|
-
return {1, r.userId, r.jti, r.version}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
-- KEYS[1] session key
|
|
2
|
-
-- ARGV[1] now epoch seconds
|
|
3
|
-
-- ARGV[2] touch interval
|
|
4
|
-
-- ARGV[3] new idle expiry epoch seconds (0 = no idle timeout)
|
|
5
|
-
-- ARGV[4] new absolute expiry epoch seconds (0 = no absolute timeout)
|
|
6
|
-
local raw = redis.call('GET', KEYS[1])
|
|
7
|
-
if not raw then return {0} end
|
|
8
|
-
local ok, s = pcall(cjson.decode, raw)
|
|
9
|
-
if not ok or not s.data then return {-4} end
|
|
10
|
-
local r = s.data
|
|
11
|
-
if r.status ~= 'active' then return {-1} end
|
|
12
|
-
local now = tonumber(ARGV[1])
|
|
13
|
-
if tonumber(r.expiresAt) <= now then return {-2} end
|
|
14
|
-
if r.absoluteExpiresAt and r.absoluteExpiresAt ~= cjson.null and tonumber(r.absoluteExpiresAt) > 0 and tonumber(r.absoluteExpiresAt) <= now then return {-2} end
|
|
15
|
-
if r.idleExpiresAt and tonumber(r.idleExpiresAt) > 0 and tonumber(r.idleExpiresAt) <= now then return {-3} end
|
|
16
|
-
if now - tonumber(r.lastAccessedAt) < tonumber(ARGV[2]) then return {2} end
|
|
17
|
-
local idle = tonumber(ARGV[3])
|
|
18
|
-
local absolute = tonumber(ARGV[4])
|
|
19
|
-
if absolute > 0 and idle > absolute then idle = absolute end
|
|
20
|
-
r.lastAccessedAt = now
|
|
21
|
-
r.idleExpiresAt = idle > 0 and idle or cjson.null
|
|
22
|
-
r.version = tonumber(r.version) + 1
|
|
23
|
-
local wrapper = {v=1, data=r}
|
|
24
|
-
local encoded = cjson.encode(wrapper)
|
|
25
|
-
local ttl = tonumber(r.expiresAt) - now
|
|
26
|
-
if ttl <= 0 then return {-2} end
|
|
27
|
-
redis.call('SET', KEYS[1], encoded, 'XX', 'EX', ttl)
|
|
28
|
-
return {1, r.version, idle}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
-- KEYS[1] session key
|
|
2
|
-
-- ARGV[1] expected version
|
|
3
|
-
-- ARGV[2] now
|
|
4
|
-
-- ARGV[3] serialized replacement
|
|
5
|
-
local raw = redis.call('GET', KEYS[1])
|
|
6
|
-
if not raw then return {0} end
|
|
7
|
-
local ok, s = pcall(cjson.decode, raw)
|
|
8
|
-
if not ok or not s.data then return {-4} end
|
|
9
|
-
if s.data.status ~= 'active' then return {-3} end
|
|
10
|
-
if tonumber(s.data.version) ~= tonumber(ARGV[1]) then return {-2, s.data.version} end
|
|
11
|
-
local replacement = ARGV[3]
|
|
12
|
-
local ok2, parsed = pcall(cjson.decode, replacement)
|
|
13
|
-
if not ok2 or not parsed.data then return {-4} end
|
|
14
|
-
if parsed.data.userId ~= s.data.userId or parsed.data.jti ~= s.data.jti or parsed.data.id ~= s.data.id or parsed.data.createdAt ~= s.data.createdAt or parsed.data.absoluteExpiresAt ~= s.data.absoluteExpiresAt then return {-5} end
|
|
15
|
-
local ttl = tonumber(s.data.expiresAt) - tonumber(ARGV[2])
|
|
16
|
-
if ttl <= 0 then return {-1} end
|
|
17
|
-
redis.call('SET', KEYS[1], replacement, 'XX', 'EX', ttl)
|
|
18
|
-
return {1}
|