encoded_token 1.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 94f6aff78bcde0cd3cd00402ebf39c4ae1967529448e3d3f821329ad2e469e52
4
+ data.tar.gz: 34a07e6096e29a16c13adc2e59add378174d8b43796959d76b0e46e38028ebd8
5
+ SHA512:
6
+ metadata.gz: bffcc7452c6b6edbb1c4e82da354a925c5804583579e537344260c7b1d0f8145a9fd171adc676982a0dc808cf52f3195cb8b6036c9847b2893438d48a864d462
7
+ data.tar.gz: 054e5e5e05415062b40404a5ef0bd231d393840c30169375f6de1257b652b242315b234a14715dad933c3bca584a8ddfeecba070461c28539116e5b239427e2a
@@ -0,0 +1,280 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # EncodedToken::Base
5
+ #
6
+ # The core configuration settings used for encoding and decoding, along
7
+ # with the methods for initialization and verification.
8
+ #
9
+ # Encoding is achived though a variation of Alberti's cipher for
10
+ # multiple Ciphertext Alphabets.
11
+ # (https://en.wikipedia.org/wiki/Alberti_cipher
12
+ #
13
+ class EncodedToken
14
+ module Base
15
+
16
+ # ======================================================================
17
+ # Configuration
18
+ # ======================================================================
19
+
20
+ HEX_NUMS = ('0'..'9').to_a
21
+ HEX_CHARS = ('a'..'f').to_a + ('A'..'F').to_a
22
+ SPECIAL_CHARS = ['-']
23
+ HEX_TEXT = (HEX_NUMS + HEX_CHARS + SPECIAL_CHARS).join # :nodoc:
24
+
25
+ CIPHER_CHARS = ('0'..'9').to_a + ('a'..'z').to_a + ('A'..'Z').to_a
26
+ CIPHER_TEXT = CIPHER_CHARS.join # :nodoc:
27
+ CIPHER_COUNT = 16 # :nodoc:
28
+ TARGET_SIZE = 55 # :nodoc:
29
+
30
+ private_constant :HEX_NUMS, :HEX_CHARS, :SPECIAL_CHARS, :CIPHER_CHARS
31
+
32
+ @@seed = nil
33
+ @@ciphers = nil
34
+ @@keylist = nil
35
+
36
+
37
+
38
+ # ======================================================================
39
+ # Public Methods
40
+ # ======================================================================
41
+
42
+ ##
43
+ # Sets the seed to be used in generating a random encoding
44
+ #
45
+ # [returns:]
46
+ # - true on success
47
+ #
48
+ # [on error:]
49
+ # - raises an exception
50
+ #
51
+ def seed=(new_seed)
52
+ if @@seed
53
+ fail_with_seed_already_set
54
+ else
55
+ @@seed = parse_seed(new_seed)
56
+ generate_ciphers
57
+ return true
58
+ end
59
+ end
60
+
61
+
62
+
63
+ # ======================================================================
64
+ # Class Private Methods
65
+ # ======================================================================
66
+ private
67
+
68
+
69
+ # parse the new seed to ensure it is an integer
70
+ #
71
+ # return the Integer seed on success, otherwise raises an error
72
+ #
73
+ def parse_seed(new_seed)
74
+ if valid_integer?(new_seed)
75
+ return new_seed.to_i.abs
76
+ else
77
+ fail_with_invalid_seed_argument
78
+ end
79
+ end
80
+
81
+
82
+
83
+ # Generate a set of ciphers
84
+ #
85
+ # returns - a Hash of ciphers with a CIPHER_CHARS character for each key
86
+ #
87
+ def generate_ciphers
88
+ ciphers = {}
89
+ random = Random.new(__seed)
90
+ keys = CIPHER_CHARS.sample(__cipher_count, random: random).sort_by(&:downcase)
91
+ @@keylist = keys
92
+
93
+ # for each key, add a hash of the padding chareacter count
94
+ # and a cipher string to be used for encryption, using a different seed each time
95
+ keys.each_with_index do |key, idx|
96
+ ciphers[key] = {
97
+ padding: random.rand(0..10),
98
+ cipher_text: CIPHER_CHARS.sample(HEX_TEXT.size, random: random).join
99
+ }
100
+ end
101
+
102
+ @@ciphers = ciphers
103
+ end
104
+
105
+
106
+
107
+ # return the next cypher key after the given key, looping to the first when required
108
+ def rotate_cipher_key(key)
109
+ idx = __keylist.index(key) + 1
110
+ __keylist[idx] || __keylist.first
111
+ end
112
+
113
+
114
+
115
+ # Validity
116
+ # ======================================================================
117
+
118
+ # checks if the seed had been set
119
+ # - returns true if the seed is set
120
+ # - set the seed if missing and a valid ENV['ENCODED_TOKEN_SEED'] is present
121
+ #
122
+ def assert_valid_seed!
123
+ case
124
+ when !!@@seed
125
+ true
126
+
127
+ when !!ENV['ENCODED_TOKEN_SEED']
128
+ assert_valid_env!
129
+ self.seed = ENV['ENCODED_TOKEN_SEED'].to_i
130
+
131
+ else
132
+ fail RuntimeError, "Encryption seed must be set before using EncodedToken."\
133
+ " Set the seed with EncodedToken.seed=(xxx)."
134
+ end
135
+ end
136
+
137
+
138
+
139
+ # check ENV['ENCODED_TOKEN_SEED'] is a string integer
140
+ def assert_valid_env!
141
+ begin
142
+ if valid_integer?(ENV['ENCODED_TOKEN_SEED'])
143
+ return true
144
+ else
145
+ fail
146
+ end
147
+ rescue
148
+ fail RuntimeError, "ENV['ENCODED_TOKEN_SEED'] must be a string encoded Integer."
149
+ end
150
+ end
151
+
152
+
153
+
154
+ # Return true if the given String only contains hex text
155
+ def valid_hex_text?(val)
156
+ (val.chars - __hex_text.chars).empty?
157
+ end
158
+
159
+
160
+
161
+ # returns true if the given id is is an integer, else false
162
+ #
163
+ # id - and Inetger or String
164
+ #
165
+ def valid_integer?(id)
166
+ sid = id.to_s
167
+ sid.to_i.to_s == sid
168
+ rescue
169
+ false
170
+ end
171
+
172
+
173
+
174
+ # Return true if the given String only contains cipher text text
175
+ def valid_token_text?(val)
176
+ (val.chars - __cipher_text.chars).empty?
177
+ end
178
+
179
+
180
+
181
+ # returns true if the given id is a UUID, else false
182
+ #
183
+ # id - String uuid
184
+ #
185
+ def valid_uuid_format?(id)
186
+ uuid_regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
187
+ uuid_regex.match?(id.downcase)
188
+ rescue
189
+ false
190
+ end
191
+
192
+
193
+
194
+ # Configuration Attributes
195
+ # ======================================================================
196
+
197
+ # return the number of ciphers
198
+ def __cipher_count
199
+ CIPHER_COUNT
200
+ end
201
+
202
+
203
+
204
+ # return the cipher keylist
205
+ def __keylist
206
+ @@keylist
207
+ end
208
+
209
+
210
+
211
+ # return the constant cypher text
212
+ def __cipher_text
213
+ CIPHER_TEXT
214
+ end
215
+
216
+
217
+
218
+ # return the base ciphers hash
219
+ def __ciphers
220
+ @@ciphers
221
+ end
222
+
223
+
224
+
225
+ # return the constant hex text
226
+ def __hex_text
227
+ HEX_TEXT
228
+ end
229
+
230
+
231
+
232
+ # return seed
233
+ def __seed
234
+ @@seed
235
+ end
236
+
237
+
238
+
239
+ # return the target size
240
+ def __target_size
241
+ TARGET_SIZE
242
+ end
243
+
244
+
245
+
246
+ # Error Messages
247
+ # ======================================================================
248
+
249
+ # error: invalid ID supplied
250
+ def fail_with_invalid_id_argument
251
+ fail_with ArgumentError,
252
+ ":id must be an Integer, a String integer or a String UUID."
253
+ end
254
+
255
+
256
+
257
+ # error: Seed is already set
258
+ def fail_with_seed_already_set
259
+ fail_with ArgumentError,
260
+ "EncodedToken seed has alreay been set to #{@@seed}."
261
+ end
262
+
263
+
264
+
265
+ # error: invalid Seed supplied
266
+ def fail_with_invalid_seed_argument
267
+ fail_with ArgumentError,
268
+ ":seed must be an Integer, preferably with at least 5 digits."
269
+ end
270
+
271
+
272
+
273
+ # default error message header
274
+ def fail_with(error_klass, message)
275
+ fail error_klass, "\n\nERROR :=> EncodedToken: #{message}\n\n"
276
+ end
277
+
278
+
279
+ end #module
280
+ end #class
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # EncodedToken::Encoder
5
+ #
6
+ # The methods required to decode a token.
7
+ #
8
+ class EncodedToken # :nodoc:
9
+ module Decoder
10
+
11
+ # ======================================================================
12
+ # Public Methods
13
+ # ======================================================================
14
+
15
+ ##
16
+ # Decode a previously encoded token to return the original ID
17
+ #
18
+ # [args:]
19
+ # - *token* [String]
20
+ #
21
+ # [returns:]
22
+ # - a String with the original ID
23
+ #
24
+ # [on error:]
25
+ # - an invalid String token returns +nil+
26
+ # - otherwise an exception will be raised
27
+ #
28
+ # *examples:*
29
+ #
30
+ # EncodedToken.decode!("KY3bnaRGmyy6yJS3imWr1dcWtzDYvZjpIAYyCUo5PEKPFvQgtTTed")
31
+ # #=> "12345"
32
+ #
33
+ # EncodedToken.decode!("3gDwO7r4UJYeBYDBLU94MqjZQm0SToSE29ACDNcw0xf4QusZKxQHJ")
34
+ # #=> "12345"
35
+ #
36
+ # EncodedToken.decode!("pAi1SmpKgFAchh76EoLbYLeXVQmLwmMlH2v1zDVeufioKGr0709Qw")
37
+ # #=> "468a5eeb-0cda-4c99-8dba-6a96c33003e0"
38
+ #
39
+ # EncodedToken.decode!("abcdefghijklmnopqrstuvwxyz")
40
+ # #=> nil
41
+ #
42
+ # EncodedToken.decode!(:test)
43
+ # #=> Token is not a string. (RuntimeError)
44
+ #
45
+ def decode!(token)
46
+ assert_valid_seed!
47
+
48
+ token = sanitize_token(token)
49
+ id = parse_token(token)
50
+
51
+ # is it a UUID or numeric ID
52
+ if valid_integer?(id) || valid_uuid_format?(id)
53
+ return id
54
+ else
55
+ return nil
56
+ end
57
+ end
58
+
59
+
60
+
61
+ ##
62
+ # Decode a previously encoded token to return the original ID
63
+ #
64
+ # [args:]
65
+ # - *token* [String]
66
+ #
67
+ # [returns:]
68
+ # - a String with the original ID
69
+ #
70
+ # [on error:]
71
+ # - returns +nil+
72
+ #
73
+ # *examples:*
74
+ #
75
+ # EncodedToken.decode("KY3bnaRGmyy6yJS3imWr1dcWtzDYvZjpIAYyCUo5PEKPFvQgtTTed")
76
+ # #=> "12345"
77
+ #
78
+ # EncodedToken.decode("3gDwO7r4UJYeBYDBLU94MqjZQm0SToSE29ACDNcw0xf4QusZKxQHJ")
79
+ # #=> "12345"
80
+ #
81
+ # EncodedToken.decode("pAi1SmpKgFAchh76EoLbYLeXVQmLwmMlH2v1zDVeufioKGr0709Qw")
82
+ # #=> "4ef2091f-023b-4af6-9e9f-f46465f897ba"
83
+ #
84
+ # EncodedToken.decode("abcdefghijklmnopqrstuvwxyz")
85
+ # #=> nil
86
+ #
87
+ # EncodedToken.decode(:test)
88
+ # #=> nil
89
+ #
90
+ def decode(id)
91
+ decode!(id)
92
+ rescue
93
+ nil
94
+ end
95
+
96
+
97
+ # ======================================================================
98
+ # Private Methods
99
+ # ======================================================================
100
+ #
101
+ private
102
+
103
+
104
+ # ensures the given token is valid to decode
105
+ #
106
+ # token [String] - a properly encoded String
107
+ #
108
+ # returns - a String duplicate of the given token
109
+ #
110
+ # on error: - a RuntimeError is raised
111
+ #
112
+ # NOTE: - we return a duplicate so the original is not changed later
113
+ # in the process when shifting segments
114
+ #
115
+ def sanitize_token(token)
116
+ fail 'Token is not a string.' unless token.is_a?(String)
117
+ fail 'Invalid token characters' unless valid_token_text?(token)
118
+ fail 'Invalid token cipher.' unless __keylist.include?(token[0])
119
+ token.dup
120
+ end
121
+
122
+
123
+
124
+ # Parses the token to retrieve the original ID
125
+ #
126
+ # token [String] - the encoded token
127
+ #
128
+ # returns [String] - the original ID
129
+ #
130
+ def parse_token(token)
131
+ key = token[0]
132
+ id_size = decrypt_size(token[1,2], key)
133
+ padding = __ciphers[key][:padding]
134
+ enc_id = token[padding + 3, id_size]
135
+
136
+ return decrypt(enc_id, key)
137
+ end
138
+
139
+
140
+
141
+ # returns the Integer size of the id
142
+ #
143
+ # enc_size - the encrypted ID
144
+ # key - the cipher key to use
145
+ #
146
+ def decrypt_size(enc_size, key)
147
+ decrypt(enc_size, key).hex
148
+ end
149
+
150
+
151
+
152
+ # decrypt the id using the cipher text from the given key.
153
+ # - rotate the cipher every character
154
+ #
155
+ # enc_id - encoded String ID
156
+ # key - base cipher key to use
157
+ #
158
+ # on error - rasies an exception (invalid cipher chars, etc)
159
+ #
160
+ def decrypt(enc_id, key)
161
+ id = ""
162
+ enc_key = key
163
+
164
+ enc_id.each_char do |char|
165
+ enc_key = rotate_cipher_key(enc_key)
166
+ cipher_text = __ciphers[enc_key][:cipher_text]
167
+
168
+ id += __hex_text[cipher_text.index(char)]
169
+ end
170
+
171
+ return id
172
+ rescue
173
+ fail 'Invalid token characters'
174
+ end
175
+
176
+ end #module
177
+ end #class
178
+
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # EncodedToken::Encoder
5
+ #
6
+ # The methods required to encode a token with an Integer ID or String UUID.
7
+ #
8
+ class EncodedToken # :nodoc:
9
+ module Encoder
10
+
11
+ # Public Methods
12
+ # ======================================================================
13
+
14
+ ##
15
+ # Generates a Secure Token from the given ID
16
+ #
17
+ # [args:]
18
+ # - *id* [Integer, String] - the ID or UUID to encode
19
+ # - eg. 12345, "12345", "468a5eeb-0cda-4c99-8dba-6a96c33003e0"
20
+ #
21
+ # [returns:]
22
+ # - a web-safe, variable length String of alphanumeric characters
23
+ #
24
+ # [on error:]
25
+ # - raises an exception based on the error
26
+ #
27
+ # *examples:*
28
+ #
29
+ # EncodedToken.encode!(12345)
30
+ # # => "KY3bnaRGmyy6yJS3imWr1dcWtzDYvZjpIAYyCUo5PEKPFvQgtTTed"
31
+ #
32
+ # EncodedToken.encode!("12345")
33
+ # # => "3gDwO7r4UJYeBYDBLU94MqjZQm0SToSE29ACDNcw0xf4QusZKxQHJ"
34
+ #
35
+ # EncodedToken.encode!("468a5eeb-0cda-4c99-8dba-6a96c33003e0")
36
+ # # => "pAi1SmpKgFAchh76EoLbYLeXVQmLwmMlH2v1zDVeufioKGr0709Qw"
37
+ #
38
+ # EncodedToken.encode!(:test)
39
+ # # => EncodedToken: :id must be an Integer, a String integer or a String UUID. (RuntimeError)
40
+ #
41
+ def encode!(id)
42
+ assert_valid_seed!
43
+ assert_valid_id!(id)
44
+ generate_token(id)
45
+ end
46
+
47
+
48
+
49
+ ##
50
+ # Generates a Secure Token from the given ID
51
+ #
52
+ # [args:]
53
+ # - *id* [Integer, String] - the ID or UUID to encode
54
+ # - eg. 12345, "12345", "468a5eeb-0cda-4c99-8dba-6a96c33003e0"
55
+ #
56
+ # [returns:]
57
+ # - a web-safe, variable length String of alphanumeric characters
58
+ #
59
+ # [on error:]
60
+ # - raises an ArgumentError
61
+ #
62
+ # *examples:*
63
+ #
64
+ # EncodedToken.encode(12345)
65
+ # # => "KY3bnaRGmyy6yJS3imWr1dcWtzDYvZjpIAYyCUo5PEKPFvQgtTTed"
66
+ #
67
+ # EncodedToken.encode("12345")
68
+ # # => "3gDwO7r4UJYeBYDBLU94MqjZQm0SToSE29ACDNcw0xf4QusZKxQHJ"
69
+ #
70
+ # EncodedToken.encode("468a5eeb-0cda-4c99-8dba-6a96c33003e0")
71
+ # # => "pAi1SmpKgFAchh76EoLbYLeXVQmLwmMlH2v1zDVeufioKGr0709Qw"
72
+ #
73
+ # EncodedToken.encode(:test)
74
+ # # => EncodedToken: :id must be an Integer, a String integer or a String UUID. (RuntimeError)
75
+ #
76
+ #
77
+ def encode(id)
78
+ encode!(id)
79
+ rescue ArgumentError
80
+ fail_with_invalid_id_argument
81
+ end
82
+
83
+
84
+
85
+ # ======================================================================
86
+ # Class Private Methods
87
+ # ======================================================================
88
+ #
89
+ private
90
+
91
+
92
+
93
+ # ensures the given ID is valid to encode
94
+ #
95
+ # id - an Integer, numerical String integer or UUID
96
+ # - max size of 255 characters
97
+ # - contain only hex charatacters + '-'
98
+ #
99
+ # returns - true if valid
100
+ #
101
+ # on error: - an ArgumentError is raised
102
+ #
103
+ def assert_valid_id!(id)
104
+ sid = id.to_s
105
+
106
+ fail if sid.size < 1
107
+ fail if sid.size > 255
108
+ fail unless valid_hex_text?(sid)
109
+ fail unless valid_integer?(id) || valid_uuid_format?(id)
110
+
111
+ return true
112
+
113
+ rescue
114
+ fail_with_invalid_id_argument
115
+ end
116
+
117
+
118
+
119
+ # generates the token
120
+ #
121
+ # id - Integer, String integer or String UUID
122
+ #
123
+ # returns - an alphanumeric String token
124
+ #
125
+ # Note - token comprises [key, id_size, left_padding, enc_id, right_padding]
126
+ #
127
+ def generate_token(id)
128
+ # stringify the id
129
+ sid = id.to_s
130
+
131
+ # select a random cipher key
132
+ token = key = __keylist.sample
133
+
134
+ # encrypt the id size
135
+ token += encrypt_size(sid, key)
136
+
137
+ # generate the left padding
138
+ token += random_characters(__ciphers[key][:padding])
139
+
140
+ # encrypt the id
141
+ token += encrypt(sid, key)
142
+
143
+ # generate right padding
144
+ count = (__target_size - token.size).clamp(0, __target_size)
145
+ token += random_characters(count)
146
+
147
+ # return the new token
148
+ return token
149
+ end
150
+
151
+
152
+
153
+ # return the encrypted size of the id
154
+ #
155
+ # returns a 2-character String
156
+ #
157
+ # note - we convert to hex to allow for strings up to 255 chars
158
+ #
159
+ def encrypt_size(id, key)
160
+ hex_size = id.size.to_s(16).rjust(2, '0')
161
+
162
+ encrypt(hex_size, key)
163
+ end
164
+
165
+
166
+
167
+ # encrypt the id using the cipher text from the given key.
168
+ # - rotate the cipher every character to avoid sequential valuies like id: 1000
169
+ #
170
+ def encrypt(id, key)
171
+ enc_id = []
172
+ encipher_key = key
173
+
174
+ id.to_s.each_char do |char|
175
+ encipher_key = rotate_cipher_key(encipher_key)
176
+ cipher_text = __ciphers[encipher_key][:cipher_text]
177
+
178
+ enc_id << cipher_text[__hex_text.index(char)]
179
+ end
180
+
181
+ return enc_id.join
182
+ end
183
+
184
+
185
+
186
+ # generate a String of alphanumeric characters ot the given size
187
+ #
188
+ def random_characters(size)
189
+ SecureRandom.alphanumeric(size)
190
+ end
191
+
192
+ end #module
193
+ end #class
194
+
195
+
196
+
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ ##
5
+ # EncodedToken version details
6
+ #
7
+ class EncodedToken # :nodoc:
8
+
9
+ ##
10
+ # The EncodedToken gem version.
11
+ #
12
+ # [returns:]
13
+ # - the version of the currently loaded EncodedToken as a <tt>Gem::Version</tt>
14
+ #
15
+ def self.gem_version
16
+ Gem::Version.new VERSION::STRING
17
+ end
18
+
19
+
20
+
21
+ module VERSION # :nodoc: all
22
+
23
+ MAJOR = 1
24
+ MINOR = 0
25
+ TINY = 2
26
+ # MICRO = ''
27
+
28
+ STRING = [MAJOR, MINOR, TINY].compact.join(".")
29
+ # STRING = [MAJOR, MINOR, TINY, MICRO].compact.join(".")
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # = EncodedToken
5
+ #
6
+ # Encodes a UUID or numeric ID to produce a Secure Token,
7
+ # then decodes the Secure Token to return the origianl ID.
8
+ #
9
+ # - The given ID is encoded using a substitution cipher, then padded
10
+ # with alphanumeric characters to a random length.
11
+ #
12
+ # - Multiple substituion ciphers are used to improve security.
13
+ #
14
+ # *examples:*
15
+ #
16
+ # EncodedToken.encode(12345)
17
+ # # => "b4ex6AEB62jlBGpVAGNou8iRmD7pnHGHafQlAHB7w0J"
18
+ #
19
+ # EncodedToken.decode("b4ex6AEB62jlBGpVAGNou8iRmD7pnHGHafQlAHB7w0J")
20
+ # # => "12345"
21
+ #
22
+ class EncodedToken
23
+
24
+
25
+ # ======================================================================
26
+ # Macros
27
+ # ======================================================================
28
+
29
+ require "securerandom"
30
+ require_relative "encoded_token/base.rb"
31
+ require_relative "encoded_token/encoder.rb"
32
+ require_relative "encoded_token/decoder.rb"
33
+
34
+ extend EncodedToken::Base
35
+ extend EncodedToken::Encoder
36
+ extend EncodedToken::Decoder
37
+
38
+
39
+ # ======================================================================
40
+ # Public Instance Methods
41
+ # ======================================================================
42
+
43
+ # This is an abstract class, so ensure no instantiation
44
+ def initialize # :nodoc:
45
+ raise NotImplementedError.new("SecureToken is an abstract class and cannot be instantiated.")
46
+ end
47
+
48
+ end #class
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: encoded_token
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - CodeMeister
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-10-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Stop hitting the DB with every secure-token submission. Encoded Tokens
14
+ have the ID, or UUID, encoded within the token itself - increasing both security
15
+ and performance. Coded in plain Ruby, EncodedToken is framework agnostic.
16
+ email: encoded_token@codemeister.dev
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/encoded_token.rb
22
+ - lib/encoded_token/base.rb
23
+ - lib/encoded_token/decoder.rb
24
+ - lib/encoded_token/encoder.rb
25
+ - lib/encoded_token/version.rb
26
+ homepage: https://github.com/Rubology/encoded_token
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ homepage_uri: https://github.com/Rubology/encoded_token
31
+ source_code_uri: https://github.com/Rubology/encoded_token
32
+ changelog_uri: https://github.com/Rubology/encoded_token/blob/master/CHANGELOG.md
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 2.5.0
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubygems_version: 3.3.22
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: A better, more secure and efficient way to manage secure-tokens - by encoding
52
+ the ID, or UUID, within the token itself.
53
+ test_files: []