parse-stack-next 4.5.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/.bundle/config +2 -0
- data/.env.sample +112 -0
- data/.env.test +10 -0
- data/.github/workflows/ruby.yml +36 -0
- data/.gitignore +49 -0
- data/.ruby-version +1 -0
- data/.solargraph.yml +22 -0
- data/CHANGELOG.md +5816 -0
- data/Gemfile +30 -0
- data/Gemfile.lock +175 -0
- data/LICENSE.txt +23 -0
- data/Makefile +63 -0
- data/README.md +5655 -0
- data/Rakefile +573 -0
- data/bin/console +38 -0
- data/bin/parse-console +136 -0
- data/bin/server +17 -0
- data/bin/setup +7 -0
- data/config/parse-config.json +12 -0
- data/docs/TEST_SERVER.md +271 -0
- data/docs/_config.yml +1 -0
- data/docs/mcp_guide.md +3484 -0
- data/docs/mongodb_direct_guide.md +1348 -0
- data/docs/mongodb_index_optimization_guide.md +631 -0
- data/examples/transaction_example.rb +219 -0
- data/lib/parse/acl_scope.rb +728 -0
- data/lib/parse/agent/cancellation_token.rb +80 -0
- data/lib/parse/agent/constraint_translator.rb +480 -0
- data/lib/parse/agent/describe.rb +420 -0
- data/lib/parse/agent/errors.rb +133 -0
- data/lib/parse/agent/mcp_client.rb +557 -0
- data/lib/parse/agent/mcp_dispatcher.rb +1023 -0
- data/lib/parse/agent/mcp_rack_app.rb +1143 -0
- data/lib/parse/agent/mcp_server.rb +376 -0
- data/lib/parse/agent/metadata_audit.rb +259 -0
- data/lib/parse/agent/metadata_dsl.rb +733 -0
- data/lib/parse/agent/metadata_registry.rb +794 -0
- data/lib/parse/agent/pipeline_validator.rb +82 -0
- data/lib/parse/agent/prompts.rb +351 -0
- data/lib/parse/agent/rate_limiter.rb +158 -0
- data/lib/parse/agent/relation_graph.rb +162 -0
- data/lib/parse/agent/result_formatter.rb +453 -0
- data/lib/parse/agent/tools.rb +5489 -0
- data/lib/parse/agent.rb +3249 -0
- data/lib/parse/api/aggregate.rb +79 -0
- data/lib/parse/api/all.rb +26 -0
- data/lib/parse/api/analytics.rb +18 -0
- data/lib/parse/api/batch.rb +33 -0
- data/lib/parse/api/cloud_functions.rb +58 -0
- data/lib/parse/api/config.rb +125 -0
- data/lib/parse/api/files.rb +29 -0
- data/lib/parse/api/hooks.rb +117 -0
- data/lib/parse/api/objects.rb +146 -0
- data/lib/parse/api/path_segment.rb +75 -0
- data/lib/parse/api/push.rb +20 -0
- data/lib/parse/api/schema.rb +49 -0
- data/lib/parse/api/server.rb +50 -0
- data/lib/parse/api/sessions.rb +24 -0
- data/lib/parse/api/users.rb +250 -0
- data/lib/parse/atlas_search/index_manager.rb +353 -0
- data/lib/parse/atlas_search/result.rb +204 -0
- data/lib/parse/atlas_search/search_builder.rb +604 -0
- data/lib/parse/atlas_search/session.rb +253 -0
- data/lib/parse/atlas_search.rb +995 -0
- data/lib/parse/client/authentication.rb +97 -0
- data/lib/parse/client/batch.rb +234 -0
- data/lib/parse/client/body_builder.rb +240 -0
- data/lib/parse/client/caching.rb +203 -0
- data/lib/parse/client/logging.rb +293 -0
- data/lib/parse/client/profiling.rb +181 -0
- data/lib/parse/client/protocol.rb +91 -0
- data/lib/parse/client/request.rb +233 -0
- data/lib/parse/client/response.rb +208 -0
- data/lib/parse/client.rb +1104 -0
- data/lib/parse/clp_scope.rb +361 -0
- data/lib/parse/live_query/circuit_breaker.rb +256 -0
- data/lib/parse/live_query/client.rb +1001 -0
- data/lib/parse/live_query/configuration.rb +224 -0
- data/lib/parse/live_query/event.rb +115 -0
- data/lib/parse/live_query/event_queue.rb +272 -0
- data/lib/parse/live_query/health_monitor.rb +214 -0
- data/lib/parse/live_query/logging.rb +149 -0
- data/lib/parse/live_query/subscription.rb +294 -0
- data/lib/parse/live_query.rb +163 -0
- data/lib/parse/lookup_rewriter.rb +445 -0
- data/lib/parse/model/acl.rb +968 -0
- data/lib/parse/model/associations/belongs_to.rb +275 -0
- data/lib/parse/model/associations/collection_proxy.rb +435 -0
- data/lib/parse/model/associations/has_many.rb +597 -0
- data/lib/parse/model/associations/has_one.rb +158 -0
- data/lib/parse/model/associations/pointer_collection_proxy.rb +134 -0
- data/lib/parse/model/associations/relation_collection_proxy.rb +177 -0
- data/lib/parse/model/bytes.rb +62 -0
- data/lib/parse/model/classes/audience.rb +262 -0
- data/lib/parse/model/classes/installation.rb +363 -0
- data/lib/parse/model/classes/job_schedule.rb +153 -0
- data/lib/parse/model/classes/job_status.rb +264 -0
- data/lib/parse/model/classes/product.rb +75 -0
- data/lib/parse/model/classes/push_status.rb +263 -0
- data/lib/parse/model/classes/role.rb +751 -0
- data/lib/parse/model/classes/session.rb +201 -0
- data/lib/parse/model/classes/user.rb +943 -0
- data/lib/parse/model/clp.rb +544 -0
- data/lib/parse/model/core/actions.rb +1268 -0
- data/lib/parse/model/core/builder.rb +139 -0
- data/lib/parse/model/core/create_lock.rb +386 -0
- data/lib/parse/model/core/describe.rb +382 -0
- data/lib/parse/model/core/enhanced_change_tracking.rb +159 -0
- data/lib/parse/model/core/errors.rb +38 -0
- data/lib/parse/model/core/fetching.rb +566 -0
- data/lib/parse/model/core/field_guards.rb +220 -0
- data/lib/parse/model/core/indexing.rb +382 -0
- data/lib/parse/model/core/parse_reference.rb +407 -0
- data/lib/parse/model/core/properties.rb +809 -0
- data/lib/parse/model/core/querying.rb +491 -0
- data/lib/parse/model/core/schema.rb +202 -0
- data/lib/parse/model/core/search_indexing.rb +174 -0
- data/lib/parse/model/date.rb +88 -0
- data/lib/parse/model/email.rb +213 -0
- data/lib/parse/model/file.rb +527 -0
- data/lib/parse/model/geojson.rb +271 -0
- data/lib/parse/model/geopoint.rb +261 -0
- data/lib/parse/model/model.rb +260 -0
- data/lib/parse/model/object.rb +2068 -0
- data/lib/parse/model/phone.rb +520 -0
- data/lib/parse/model/pointer.rb +443 -0
- data/lib/parse/model/polygon.rb +406 -0
- data/lib/parse/model/push.rb +975 -0
- data/lib/parse/model/shortnames.rb +8 -0
- data/lib/parse/model/time_zone.rb +141 -0
- data/lib/parse/model/validations/uniqueness_validator.rb +97 -0
- data/lib/parse/model/validations.rb +96 -0
- data/lib/parse/mongodb.rb +2300 -0
- data/lib/parse/pipeline_security.rb +554 -0
- data/lib/parse/query/constraint.rb +198 -0
- data/lib/parse/query/constraints.rb +3279 -0
- data/lib/parse/query/cursor.rb +434 -0
- data/lib/parse/query/n_plus_one_detector.rb +445 -0
- data/lib/parse/query/operation.rb +104 -0
- data/lib/parse/query/ordering.rb +66 -0
- data/lib/parse/query.rb +7028 -0
- data/lib/parse/schema/index_migrator.rb +291 -0
- data/lib/parse/schema/search_index_migrator.rb +289 -0
- data/lib/parse/schema.rb +494 -0
- data/lib/parse/stack/generators/rails.rb +40 -0
- data/lib/parse/stack/generators/templates/model.erb +51 -0
- data/lib/parse/stack/generators/templates/model_installation.rb +4 -0
- data/lib/parse/stack/generators/templates/model_role.rb +4 -0
- data/lib/parse/stack/generators/templates/model_session.rb +4 -0
- data/lib/parse/stack/generators/templates/model_user.rb +11 -0
- data/lib/parse/stack/generators/templates/parse.rb +12 -0
- data/lib/parse/stack/generators/templates/webhooks.rb +10 -0
- data/lib/parse/stack/railtie.rb +18 -0
- data/lib/parse/stack/tasks.rb +563 -0
- data/lib/parse/stack/version.rb +11 -0
- data/lib/parse/stack.rb +455 -0
- data/lib/parse/two_factor_auth/user_extension.rb +449 -0
- data/lib/parse/two_factor_auth.rb +310 -0
- data/lib/parse/webhooks/payload.rb +360 -0
- data/lib/parse/webhooks/registration.rb +199 -0
- data/lib/parse/webhooks/replay_protection.rb +189 -0
- data/lib/parse/webhooks.rb +510 -0
- data/lib/parse-stack-next.rb +5 -0
- data/lib/parse-stack.rb +5 -0
- data/parse-stack-next.gemspec +82 -0
- data/parse-stack.png +0 -0
- data/scripts/debug-ips.js +35 -0
- data/scripts/docker/Dockerfile.parse +13 -0
- data/scripts/docker/atlas-init.js +284 -0
- data/scripts/docker/docker-compose.atlas.yml +76 -0
- data/scripts/docker/docker-compose.test.yml +106 -0
- data/scripts/docker/mongo-init.js +21 -0
- data/scripts/eval_mcp_with_lm_studio.rb +274 -0
- data/scripts/start-parse.sh +90 -0
- data/scripts/start_mcp_server.rb +78 -0
- data/scripts/test_server_connection.rb +82 -0
- metadata +377 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
# Note: Do not require "../object" here - this file is loaded from object.rb
|
|
4
|
+
# and adding that require would create a circular dependency.
|
|
5
|
+
|
|
6
|
+
module Parse
|
|
7
|
+
# This class represents the data and columns contained in the standard Parse
|
|
8
|
+
# `_Session` collection. The Session class maintains per-device (or website) authentication
|
|
9
|
+
# information for a particular user. Whenever a User object is logged in, a new Session record, with
|
|
10
|
+
# a session token is generated. You may use a known active session token to find the corresponding
|
|
11
|
+
# user for that session. Deleting a Session record (and session token), effectively logs out the user, when making Parse requests
|
|
12
|
+
# on behalf of the user using the session token.
|
|
13
|
+
#
|
|
14
|
+
# The default schema for the {Session} class is as follows:
|
|
15
|
+
# class Parse::Session < Parse::Object
|
|
16
|
+
# # See Parse::Object for inherited properties...
|
|
17
|
+
#
|
|
18
|
+
# property :session_token
|
|
19
|
+
# property :created_with, :object
|
|
20
|
+
# property :expires_at, :date
|
|
21
|
+
# property :installation_id
|
|
22
|
+
# property :restricted, :boolean
|
|
23
|
+
#
|
|
24
|
+
# belongs_to :user
|
|
25
|
+
#
|
|
26
|
+
# # Installation where the installation_id matches.
|
|
27
|
+
# has_one :installation, ->{ where(installation_id: i.installation_id) }, scope_only: true
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# @see Parse::Object
|
|
31
|
+
class Session < Parse::Object
|
|
32
|
+
parse_class Parse::Model::CLASS_SESSION
|
|
33
|
+
|
|
34
|
+
# @!attribute created_with
|
|
35
|
+
# @return [Hash] data on how this Session was created.
|
|
36
|
+
property :created_with, :object
|
|
37
|
+
|
|
38
|
+
# @!attribute expires_at
|
|
39
|
+
# @return [Parse::Date] when the session token expires.
|
|
40
|
+
property :expires_at, :date
|
|
41
|
+
|
|
42
|
+
# @!attribute installation_id
|
|
43
|
+
# @return [String] The installation id from the Installation table.
|
|
44
|
+
# @see Installation#installation_id
|
|
45
|
+
property :installation_id
|
|
46
|
+
|
|
47
|
+
# @!attribute [r] restricted
|
|
48
|
+
# @return [Boolean] whether this session token is restricted.
|
|
49
|
+
property :restricted, :boolean
|
|
50
|
+
|
|
51
|
+
# @!attribute [r] session_token
|
|
52
|
+
# @return [String] the session token for this installation and user pair.
|
|
53
|
+
property :session_token
|
|
54
|
+
# @!attribute [r] user
|
|
55
|
+
# This property is mapped as a `belongs_to` association with the {Parse::User}
|
|
56
|
+
# class. Every session instance is tied to a specific logged in user.
|
|
57
|
+
# @return [User] the user corresponding to this session.
|
|
58
|
+
# @see User
|
|
59
|
+
belongs_to :user
|
|
60
|
+
|
|
61
|
+
# @!attribute [r] installation
|
|
62
|
+
# Returns the {Parse::Installation} where the sessions installation_id field matches the installation_id field
|
|
63
|
+
# in the {Parse::Installation} collection. This is implemented as a has_one scope.
|
|
64
|
+
# @version 1.7.1
|
|
65
|
+
# @return [Parse::Installation] The associated {Parse::Installation} tied to this session
|
|
66
|
+
has_one :installation, -> { where(installation_id: i.installation_id) }, scope_only: true
|
|
67
|
+
|
|
68
|
+
# =========================================================================
|
|
69
|
+
# Session Management - Class Methods
|
|
70
|
+
# =========================================================================
|
|
71
|
+
|
|
72
|
+
class << self
|
|
73
|
+
# Return the Session record for this session token.
|
|
74
|
+
# @param token [String] the session token
|
|
75
|
+
# @param opts [Hash] additional keyword options forwarded to the
|
|
76
|
+
# underlying client request (e.g. +cache: false+,
|
|
77
|
+
# +use_master_key: false+, +headers:+).
|
|
78
|
+
# @return [Session] the session for this token, otherwise nil.
|
|
79
|
+
def session(token, **opts)
|
|
80
|
+
# A stray :session_token in opts would be forwarded into the request
|
|
81
|
+
# stack and silently override the positional token argument. Drop it
|
|
82
|
+
# so the explicit token always wins.
|
|
83
|
+
opts.delete(:session_token)
|
|
84
|
+
response = client.fetch_session(token, **opts)
|
|
85
|
+
if response.success?
|
|
86
|
+
return Parse::Session.build response.result
|
|
87
|
+
end
|
|
88
|
+
nil
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Query scope for active (non-expired) sessions.
|
|
92
|
+
# @return [Parse::Query] a query for sessions that haven't expired
|
|
93
|
+
# @example
|
|
94
|
+
# active_sessions = Parse::Session.active.all
|
|
95
|
+
def active
|
|
96
|
+
query(:expires_at.gte => Time.now)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Query scope for expired sessions.
|
|
100
|
+
# @return [Parse::Query] a query for sessions that have expired
|
|
101
|
+
# @example
|
|
102
|
+
# expired_sessions = Parse::Session.expired.all
|
|
103
|
+
def expired
|
|
104
|
+
query(:expires_at.lt => Time.now)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Query scope for sessions belonging to a specific user.
|
|
108
|
+
# @param user [Parse::User, Parse::Pointer, String] the user or user ID
|
|
109
|
+
# @return [Parse::Query] a query for the user's sessions
|
|
110
|
+
# @example
|
|
111
|
+
# user_sessions = Parse::Session.for_user(user).all
|
|
112
|
+
def for_user(user)
|
|
113
|
+
user = Parse::User.pointer(user) if user.is_a?(String)
|
|
114
|
+
query(user: user)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Revoke (delete) all sessions for a specific user.
|
|
118
|
+
# @param user [Parse::User, Parse::Pointer, String] the user or user ID
|
|
119
|
+
# @param except [String] optional session token to exclude from revocation
|
|
120
|
+
# @return [Integer] the number of sessions revoked
|
|
121
|
+
# @example
|
|
122
|
+
# # Revoke all sessions for a user
|
|
123
|
+
# Parse::Session.revoke_all_for_user(user)
|
|
124
|
+
#
|
|
125
|
+
# # Revoke all except current session
|
|
126
|
+
# Parse::Session.revoke_all_for_user(user, except: current_session_token)
|
|
127
|
+
def revoke_all_for_user(user, except: nil)
|
|
128
|
+
sessions = for_user(user)
|
|
129
|
+
sessions = sessions.where(:session_token.ne => except) if except
|
|
130
|
+
sessions_to_revoke = sessions.all
|
|
131
|
+
sessions_to_revoke.each(&:destroy)
|
|
132
|
+
sessions_to_revoke.count
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Count active sessions for a specific user.
|
|
136
|
+
# @param user [Parse::User, Parse::Pointer, String] the user or user ID
|
|
137
|
+
# @return [Integer] count of active sessions
|
|
138
|
+
# @example
|
|
139
|
+
# count = Parse::Session.active_count_for_user(user)
|
|
140
|
+
def active_count_for_user(user)
|
|
141
|
+
for_user(user).where(:expires_at.gte => Time.now).count
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# =========================================================================
|
|
146
|
+
# Session Management - Instance Methods
|
|
147
|
+
# =========================================================================
|
|
148
|
+
|
|
149
|
+
# Check if this session has expired.
|
|
150
|
+
# @return [Boolean] true if the session has expired
|
|
151
|
+
# @example
|
|
152
|
+
# if session.expired?
|
|
153
|
+
# puts "Session has expired"
|
|
154
|
+
# end
|
|
155
|
+
def expired?
|
|
156
|
+
return false if expires_at.nil?
|
|
157
|
+
expires_at < Time.now
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Check if this session is still valid (not expired).
|
|
161
|
+
# @return [Boolean] true if the session is still valid
|
|
162
|
+
# @example
|
|
163
|
+
# if session.valid?
|
|
164
|
+
# puts "Session is still active"
|
|
165
|
+
# end
|
|
166
|
+
def valid?
|
|
167
|
+
!expired?
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Get the remaining time until this session expires.
|
|
171
|
+
# @return [Float, nil] seconds remaining until expiration, nil if no expiration, 0 if already expired
|
|
172
|
+
# @example
|
|
173
|
+
# remaining = session.time_remaining
|
|
174
|
+
# puts "Session expires in #{remaining / 3600} hours" if remaining
|
|
175
|
+
def time_remaining
|
|
176
|
+
return nil if expires_at.nil?
|
|
177
|
+
remaining = expires_at.to_time - Time.now
|
|
178
|
+
remaining > 0 ? remaining : 0
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Check if this session expires within the given duration.
|
|
182
|
+
# @param duration [Integer] number of seconds
|
|
183
|
+
# @return [Boolean] true if session expires within the duration
|
|
184
|
+
# @example
|
|
185
|
+
# if session.expires_within?(1.hour)
|
|
186
|
+
# puts "Session expires soon!"
|
|
187
|
+
# end
|
|
188
|
+
def expires_within?(duration)
|
|
189
|
+
return false if expires_at.nil?
|
|
190
|
+
expires_at < (Time.now + duration)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Revoke (delete) this session, effectively logging out the user on this device.
|
|
194
|
+
# @return [Boolean] true if successfully revoked
|
|
195
|
+
# @example
|
|
196
|
+
# session.revoke!
|
|
197
|
+
def revoke!
|
|
198
|
+
destroy
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|