ask-guests 0.1.0
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 +7 -0
- data/CHANGELOG.md +27 -0
- data/LICENSE +21 -0
- data/README.md +195 -0
- data/lib/ask/guests/active_record/json_value.rb +56 -0
- data/lib/ask/guests/active_record/session_base.rb +69 -0
- data/lib/ask/guests/active_record/session_store.rb +97 -0
- data/lib/ask/guests/budget/policy.rb +42 -0
- data/lib/ask/guests/budget/token_quota.rb +24 -0
- data/lib/ask/guests/budget/turn_limit.rb +24 -0
- data/lib/ask/guests/budget/unlimited.rb +16 -0
- data/lib/ask/guests/budget.rb +68 -0
- data/lib/ask/guests/claim.rb +49 -0
- data/lib/ask/guests/errors.rb +15 -0
- data/lib/ask/guests/rails/claim_on_authentication.rb +51 -0
- data/lib/ask/guests/rails/controller.rb +130 -0
- data/lib/ask/guests/rails/sweep_job.rb +24 -0
- data/lib/ask/guests/session.rb +103 -0
- data/lib/ask/guests/stores/base.rb +65 -0
- data/lib/ask/guests/stores/memory.rb +69 -0
- data/lib/ask/guests/sweep.rb +28 -0
- data/lib/ask/guests/token.rb +59 -0
- data/lib/ask/guests/version.rb +7 -0
- data/lib/ask/guests.rb +158 -0
- data/lib/ask-guests/active_record.rb +8 -0
- data/lib/ask-guests/rails.rb +9 -0
- data/lib/ask-guests.rb +3 -0
- data/lib/generators/ask/guests/install/install_generator.rb +66 -0
- data/lib/generators/ask/guests/install/templates/initializer.rb +39 -0
- data/lib/generators/ask/guests/install/templates/migration.rb +16 -0
- metadata +159 -0
data/lib/ask/guests.rb
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "guests/version"
|
|
4
|
+
require_relative "guests/errors"
|
|
5
|
+
require_relative "guests/token"
|
|
6
|
+
require_relative "guests/session"
|
|
7
|
+
require_relative "guests/stores/base"
|
|
8
|
+
require_relative "guests/stores/memory"
|
|
9
|
+
require_relative "guests/budget"
|
|
10
|
+
require_relative "guests/budget/policy"
|
|
11
|
+
require_relative "guests/budget/unlimited"
|
|
12
|
+
require_relative "guests/budget/turn_limit"
|
|
13
|
+
require_relative "guests/budget/token_quota"
|
|
14
|
+
require_relative "guests/claim"
|
|
15
|
+
require_relative "guests/sweep"
|
|
16
|
+
|
|
17
|
+
module Ask
|
|
18
|
+
# Anonymous, cookie-backed guest access with metered AI usage.
|
|
19
|
+
#
|
|
20
|
+
# A guest session is a durable identity for a visitor who has not signed
|
|
21
|
+
# up: a random id behind an HMAC-signed token, plus counters used to meter
|
|
22
|
+
# agent usage and a single-use claim that transfers everything the guest
|
|
23
|
+
# owns to a real owner when they authenticate.
|
|
24
|
+
#
|
|
25
|
+
# The core is framework-agnostic — plain Ruby with stdlib only. Optional
|
|
26
|
+
# adapters plug in persistence and web frameworks:
|
|
27
|
+
#
|
|
28
|
+
# require "ask-guests/active_record" # ActiveRecord store + model base
|
|
29
|
+
# require "ask-guests/rails" # controller concern, Devise hook, job
|
|
30
|
+
#
|
|
31
|
+
# @example Configuration
|
|
32
|
+
# Ask::Guests.configure do |config|
|
|
33
|
+
# config.secret = ENV.fetch("GUEST_TOKEN_SECRET")
|
|
34
|
+
# config.store = Ask::Guests::Stores::Memory.new
|
|
35
|
+
# config.policies = [Ask::Guests::Budget::TurnLimit.new(per_day: 40)]
|
|
36
|
+
# config.retention = 14 * 24 * 60 * 60 # seconds
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# @example Metering an agent turn
|
|
40
|
+
# guest = Ask::Guests.store.find(id) # or current_guest_session in Rails
|
|
41
|
+
# budget = Ask::Guests.budget
|
|
42
|
+
#
|
|
43
|
+
# unless budget.allowed?(guest)
|
|
44
|
+
# # show "sign up to keep going"
|
|
45
|
+
# end
|
|
46
|
+
# response = agent.run(...)
|
|
47
|
+
# budget.record!(guest, turns: 1, tokens: response.total_tokens)
|
|
48
|
+
#
|
|
49
|
+
# @example Claiming on sign-up
|
|
50
|
+
# Ask::Guests.claimable(:work_requests) do |session, owner|
|
|
51
|
+
# WorkRequest.where(guest_session_id: session.id)
|
|
52
|
+
# .update_all(account_id: owner.account_id, account_user_id: owner.id, guest_session_id: nil)
|
|
53
|
+
# end
|
|
54
|
+
#
|
|
55
|
+
# Ask::Guests::Claim.new(session: guest, owner: account_user).call # => true/false
|
|
56
|
+
module Guests
|
|
57
|
+
class << self
|
|
58
|
+
def configure
|
|
59
|
+
yield configuration
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def configuration
|
|
63
|
+
@configuration ||= Configuration.new
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def reset_configuration!
|
|
67
|
+
@configuration = nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def secret
|
|
71
|
+
configuration.secret
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def store
|
|
75
|
+
configuration.store
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# A budget built from the current configuration. Rebuilt on each call
|
|
79
|
+
# so configuration changes (and test resets) always take effect.
|
|
80
|
+
def budget
|
|
81
|
+
Budget.new(
|
|
82
|
+
policies: configuration.policies,
|
|
83
|
+
store: configuration.store,
|
|
84
|
+
clock: configuration.clock
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Registered record-transfer handlers, run by {Guests::Claim}.
|
|
89
|
+
# @return [Hash{String => Proc}]
|
|
90
|
+
def claimables
|
|
91
|
+
@claimables ||= {}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Register a handler that transfers records the guest session owns to
|
|
95
|
+
# a real owner. Called inside the claim's transaction.
|
|
96
|
+
#
|
|
97
|
+
# Ask::Guests.claimable(:work_requests) { |session, owner| ... }
|
|
98
|
+
def claimable(name, &block)
|
|
99
|
+
raise ArgumentError, "claimable requires a block" unless block
|
|
100
|
+
|
|
101
|
+
claimables[name.to_s] = block
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def clear_claimables!
|
|
105
|
+
@claimables = {}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def sweep
|
|
109
|
+
Sweep.new(
|
|
110
|
+
store: configuration.store,
|
|
111
|
+
retention: configuration.retention,
|
|
112
|
+
clock: configuration.clock
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Configuration for the guest system. All values have working defaults
|
|
118
|
+
# except +secret+, which is required to sign and verify tokens.
|
|
119
|
+
class Configuration
|
|
120
|
+
# HMAC secret for signing guest tokens (required).
|
|
121
|
+
attr_accessor :secret
|
|
122
|
+
# Persistence adapter (see Stores::Base). Defaults to in-memory.
|
|
123
|
+
attr_accessor :store
|
|
124
|
+
# Usage policies (see Budget::TurnLimit, Budget::TokenQuota).
|
|
125
|
+
attr_accessor :policies
|
|
126
|
+
# Unclaimed sessions older than this many seconds are swept.
|
|
127
|
+
attr_accessor :retention
|
|
128
|
+
# Injectable clock returning a Time (used for daily counter rollover
|
|
129
|
+
# and sweep cutoffs).
|
|
130
|
+
attr_accessor :clock
|
|
131
|
+
# Name of the cookie holding the signed guest token (Rails adapter).
|
|
132
|
+
attr_accessor :cookie_name
|
|
133
|
+
# Flash message shown after a successful claim (Rails adapter).
|
|
134
|
+
attr_accessor :claim_notice
|
|
135
|
+
# Minimum seconds between last-seen writes while a guest browses
|
|
136
|
+
# (Rails adapter). Keeps ordinary page views from writing per request.
|
|
137
|
+
attr_accessor :touch_interval
|
|
138
|
+
# Queue for the Rails sweep job.
|
|
139
|
+
attr_accessor :sweep_queue
|
|
140
|
+
|
|
141
|
+
def initialize
|
|
142
|
+
@secret = nil
|
|
143
|
+
@store = Stores::Memory.new
|
|
144
|
+
@policies = [Budget::Unlimited.new]
|
|
145
|
+
@retention = 14 * 24 * 60 * 60
|
|
146
|
+
@clock = -> { Time.now.utc }
|
|
147
|
+
@cookie_name = "guest_session_token"
|
|
148
|
+
@claim_notice = "Welcome! We've moved your work to your account."
|
|
149
|
+
@touch_interval = 300
|
|
150
|
+
@sweep_queue = :default
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def now
|
|
154
|
+
clock.call
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ask-guests"
|
|
4
|
+
require "active_record"
|
|
5
|
+
|
|
6
|
+
require_relative "../ask/guests/active_record/json_value"
|
|
7
|
+
require_relative "../ask/guests/active_record/session_base"
|
|
8
|
+
require_relative "../ask/guests/active_record/session_store"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ask-guests"
|
|
4
|
+
require "active_support/concern"
|
|
5
|
+
require "active_job"
|
|
6
|
+
|
|
7
|
+
require_relative "../ask/guests/rails/controller"
|
|
8
|
+
require_relative "../ask/guests/rails/claim_on_authentication"
|
|
9
|
+
require_relative "../ask/guests/rails/sweep_job"
|
data/lib/ask-guests.rb
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module Ask
|
|
6
|
+
module Guests
|
|
7
|
+
module Generators
|
|
8
|
+
# bin/rails generate ask:guests:install
|
|
9
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
10
|
+
source_root File.expand_path("templates", __dir__)
|
|
11
|
+
|
|
12
|
+
desc "Creates the guest_sessions migration and ask-guests initializer"
|
|
13
|
+
|
|
14
|
+
def create_initializer
|
|
15
|
+
template "initializer.rb", "config/initializers/ask_guests.rb"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create_migration
|
|
19
|
+
timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
|
|
20
|
+
template "migration.rb", "db/migrate/#{timestamp}_create_guest_sessions.rb"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def show_readme
|
|
24
|
+
say <<~MESSAGE
|
|
25
|
+
|
|
26
|
+
ask-guests installed.
|
|
27
|
+
|
|
28
|
+
Next steps:
|
|
29
|
+
|
|
30
|
+
1. Define the model (app/models/guest_session.rb):
|
|
31
|
+
|
|
32
|
+
class GuestSession < Ask::Guests::ActiveRecord::SessionBase
|
|
33
|
+
self.table_name = "guest_sessions"
|
|
34
|
+
|
|
35
|
+
# Destroying a session sweeps everything the guest owned:
|
|
36
|
+
# has_many :work_requests, foreign_key: :guest_session_id, dependent: :destroy
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
2. Register what claiming transfers (config/initializers/ask_guests.rb).
|
|
40
|
+
|
|
41
|
+
3. Allow guests in a controller:
|
|
42
|
+
|
|
43
|
+
include Ask::Guests::Rails::Controller
|
|
44
|
+
allow_guest_access
|
|
45
|
+
before_action :require_visitor
|
|
46
|
+
|
|
47
|
+
4. Claim on authentication (Devise example):
|
|
48
|
+
|
|
49
|
+
include Ask::Guests::Rails::ClaimOnAuthentication
|
|
50
|
+
after_action :claim_guest_session, only: :create
|
|
51
|
+
|
|
52
|
+
def guest_claim_owner = current_user.account_users.first
|
|
53
|
+
|
|
54
|
+
5. Schedule the sweep:
|
|
55
|
+
|
|
56
|
+
production:
|
|
57
|
+
guests_sweep:
|
|
58
|
+
class: "Ask::Guests::Rails::SweepJob"
|
|
59
|
+
schedule: every day at 4am
|
|
60
|
+
|
|
61
|
+
MESSAGE
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Guest access configuration (ask-guests).
|
|
4
|
+
#
|
|
5
|
+
# Anonymous visitors get a signed-cookie session, metered agent usage, and
|
|
6
|
+
# a single-use claim that moves everything they own to a real account when
|
|
7
|
+
# they sign up. See https://github.com/ask-rb/ask-guests for the full guide.
|
|
8
|
+
|
|
9
|
+
Ask::Guests.configure do |config|
|
|
10
|
+
# Required: HMAC secret for guest tokens. Rotating it invalidates all
|
|
11
|
+
# outstanding guest cookies (they simply start fresh).
|
|
12
|
+
config.secret = Rails.application.secret_key_base
|
|
13
|
+
|
|
14
|
+
# Persistence. Define the model first (see the install generator output):
|
|
15
|
+
#
|
|
16
|
+
# class GuestSession < Ask::Guests::ActiveRecord::SessionBase
|
|
17
|
+
# self.table_name = "guest_sessions"
|
|
18
|
+
# has_many :work_requests, foreign_key: :guest_session_id, dependent: :destroy
|
|
19
|
+
# end
|
|
20
|
+
config.store = Ask::Guests::ActiveRecord::SessionStore.new(model: GuestSession)
|
|
21
|
+
|
|
22
|
+
# Usage caps for anonymous visitors. Signing up lifts them because a
|
|
23
|
+
# signed-in request never touches the guest budget.
|
|
24
|
+
config.policies = [
|
|
25
|
+
Ask::Guests::Budget::TurnLimit.new(per_day: 40)
|
|
26
|
+
# Ask::Guests::Budget::TokenQuota.new(per_day: 10_000)
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
# Unclaimed sessions inactive for this long are swept (seconds).
|
|
30
|
+
config.retention = 14 * 24 * 60 * 60
|
|
31
|
+
|
|
32
|
+
# What claiming transfers. Register one handler per owned model; they run
|
|
33
|
+
# inside the claim's transaction, exactly once.
|
|
34
|
+
#
|
|
35
|
+
# Ask::Guests.claimable(:work_requests) do |session, owner|
|
|
36
|
+
# WorkRequest.where(guest_session_id: session.id)
|
|
37
|
+
# .update_all(account_id: owner.account_id, account_user_id: owner.id, guest_session_id: nil)
|
|
38
|
+
# end
|
|
39
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CreateGuestSessions < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
2
|
+
def change
|
|
3
|
+
create_table :guest_sessions do |t|
|
|
4
|
+
t.jsonb :counters, null: false, default: {}
|
|
5
|
+
t.jsonb :metadata, null: false, default: {}
|
|
6
|
+
t.datetime :last_seen_at
|
|
7
|
+
t.datetime :converted_at
|
|
8
|
+
t.references :owner, polymorphic: true
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Speculative: sessions at risk of being swept.
|
|
13
|
+
add_index :guest_sessions, :converted_at
|
|
14
|
+
add_index :guest_sessions, :last_seen_at
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ask-guests
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kaka Ruto
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: minitest
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '5.25'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '5.25'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mocha
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.1'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.1'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '13.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: activerecord
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '7.1'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '7.1'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: sqlite3
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '1.4'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '1.4'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: activejob
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '7.1'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '7.1'
|
|
96
|
+
description: 'Give anonymous visitors a durable identity with metered AI access: signed
|
|
97
|
+
guest sessions, per-day turn/token budgets, single-use claiming of records into
|
|
98
|
+
a real owner on sign-up, and stale-session retention. Framework-agnostic core with
|
|
99
|
+
optional ActiveRecord and Rails adapters.'
|
|
100
|
+
email:
|
|
101
|
+
- kaka@myrrlabs.com
|
|
102
|
+
executables: []
|
|
103
|
+
extensions: []
|
|
104
|
+
extra_rdoc_files: []
|
|
105
|
+
files:
|
|
106
|
+
- CHANGELOG.md
|
|
107
|
+
- LICENSE
|
|
108
|
+
- README.md
|
|
109
|
+
- lib/ask-guests.rb
|
|
110
|
+
- lib/ask-guests/active_record.rb
|
|
111
|
+
- lib/ask-guests/rails.rb
|
|
112
|
+
- lib/ask/guests.rb
|
|
113
|
+
- lib/ask/guests/active_record/json_value.rb
|
|
114
|
+
- lib/ask/guests/active_record/session_base.rb
|
|
115
|
+
- lib/ask/guests/active_record/session_store.rb
|
|
116
|
+
- lib/ask/guests/budget.rb
|
|
117
|
+
- lib/ask/guests/budget/policy.rb
|
|
118
|
+
- lib/ask/guests/budget/token_quota.rb
|
|
119
|
+
- lib/ask/guests/budget/turn_limit.rb
|
|
120
|
+
- lib/ask/guests/budget/unlimited.rb
|
|
121
|
+
- lib/ask/guests/claim.rb
|
|
122
|
+
- lib/ask/guests/errors.rb
|
|
123
|
+
- lib/ask/guests/rails/claim_on_authentication.rb
|
|
124
|
+
- lib/ask/guests/rails/controller.rb
|
|
125
|
+
- lib/ask/guests/rails/sweep_job.rb
|
|
126
|
+
- lib/ask/guests/session.rb
|
|
127
|
+
- lib/ask/guests/stores/base.rb
|
|
128
|
+
- lib/ask/guests/stores/memory.rb
|
|
129
|
+
- lib/ask/guests/sweep.rb
|
|
130
|
+
- lib/ask/guests/token.rb
|
|
131
|
+
- lib/ask/guests/version.rb
|
|
132
|
+
- lib/generators/ask/guests/install/install_generator.rb
|
|
133
|
+
- lib/generators/ask/guests/install/templates/initializer.rb
|
|
134
|
+
- lib/generators/ask/guests/install/templates/migration.rb
|
|
135
|
+
homepage: https://github.com/ask-rb/ask-guests
|
|
136
|
+
licenses:
|
|
137
|
+
- MIT
|
|
138
|
+
metadata:
|
|
139
|
+
homepage_uri: https://github.com/ask-rb/ask-guests
|
|
140
|
+
source_code_uri: https://github.com/ask-rb/ask-guests
|
|
141
|
+
changelog_uri: https://github.com/ask-rb/ask-guests/blob/master/CHANGELOG.md
|
|
142
|
+
rdoc_options: []
|
|
143
|
+
require_paths:
|
|
144
|
+
- lib
|
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
146
|
+
requirements:
|
|
147
|
+
- - ">="
|
|
148
|
+
- !ruby/object:Gem::Version
|
|
149
|
+
version: '3.2'
|
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
|
+
requirements:
|
|
152
|
+
- - ">="
|
|
153
|
+
- !ruby/object:Gem::Version
|
|
154
|
+
version: '0'
|
|
155
|
+
requirements: []
|
|
156
|
+
rubygems_version: 4.0.18
|
|
157
|
+
specification_version: 4
|
|
158
|
+
summary: Anonymous, cookie-backed guest access for ask-rb apps
|
|
159
|
+
test_files: []
|