Module: Parse::API::Users

Included in:
Client
Defined in:
lib/parse/api/users.rb

Overview

Defines the User class interface for the Parse REST API

Instance Method Summary collapse

Instance Method Details

#create_user(body, headers: {}, **opts) ⇒ Parse::Response

Create a new user.

Parameters:

  • body (Hash)

    a hash of values related to your _User schema.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



60
61
62
63
64
65
66
67
68
# File 'lib/parse/api/users.rb', line 60

def create_user(body, headers: {}, **opts)
  headers.merge!({ Parse::Protocol::REVOCABLE_SESSION => "1" })
  if opts[:session_token].present?
    headers.merge!({ Parse::Protocol::SESSION_TOKEN => opts[:session_token] })
  end
  response = request :post, USER_PATH_PREFIX, body: body, headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  response
end

#current_user(session_token, headers: {}, **opts) ⇒ Parse::Response

Find user matching this active session token.

Parameters:

  • session_token (String)

    the Parse user session token to look up.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



48
49
50
51
52
53
# File 'lib/parse/api/users.rb', line 48

def current_user(session_token, headers: {}, **opts)
  headers.merge!({ Parse::Protocol::SESSION_TOKEN => session_token })
  response = request :get, "#{USER_PATH_PREFIX}/me", headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  response
end

#delete_user(id, headers: {}, **opts) ⇒ Parse::Response

Delete a User record given an objectId.

Parameters:

  • id (String)

    the Parse user objectId.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



100
101
102
# File 'lib/parse/api/users.rb', line 100

def delete_user(id, headers: {}, **opts)
  request :delete, "#{USER_PATH_PREFIX}/#{id}", headers: headers, opts: opts
end

#fetch_user(id, headers: {}, **opts) ⇒ Parse::Response

Fetch a User for a given objectId.

Parameters:

  • id (String)

    the user objectid

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



28
29
30
# File 'lib/parse/api/users.rb', line 28

def fetch_user(id, headers: {}, **opts)
  request :get, "#{USER_PATH_PREFIX}/#{id}", headers: headers, opts: opts
end

#find_users(query = {}, headers: {}, **opts) ⇒ Parse::Response

Find users matching a set of constraints.

Parameters:

  • query (Hash) (defaults to: {})

    query parameters.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



37
38
39
40
41
# File 'lib/parse/api/users.rb', line 37

def find_users(query = {}, headers: {}, **opts)
  response = request :get, USER_PATH_PREFIX, query: query, headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  response
end

#login(username, password, headers: {}, **opts) ⇒ Parse::Response

Login a user. Implements client-side rate limiting with exponential backoff after repeated failures to mitigate brute force attacks.

Parameters:

  • username (String)

    the Parse user username.

  • password (String)

    the Parse user's associated password.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

  • opts (Hash)

    additional options to pass to the Client request.

Returns:



164
165
166
167
168
169
170
171
172
# File 'lib/parse/api/users.rb', line 164

def (username, password, headers: {}, **opts)
  (username)
  body = { username: username, password: password }
  headers.merge!({ Parse::Protocol::REVOCABLE_SESSION => "1" })
  response = request :post, LOGIN_PATH, body: body, headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  (username, response.success?)
  response
end

#login_with_mfa(username, password, mfa_token, headers: {}, **opts) ⇒ Parse::Response

Login a user with MFA (Multi-Factor Authentication).

This method handles Parse Server's MFA adapter which requires both standard credentials AND an MFA token when MFA is enabled for the user.

Examples:

response = client.("john", "password123", "123456")

Parameters:

  • username (String)

    the Parse user username.

  • password (String)

    the Parse user's associated password.

  • mfa_token (String)

    the TOTP code from authenticator app or recovery code.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

  • opts (Hash)

    additional options to pass to the Client request.

Returns:



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/parse/api/users.rb', line 188

def (username, password, mfa_token, headers: {}, **opts)
  (username)
  # Parse Server expects authData to be sent with POST for MFA login
  body = {
    username: username,
    password: password,
    authData: {
      mfa: {
        token: mfa_token,
      },
    },
  }
  headers.merge!({ Parse::Protocol::REVOCABLE_SESSION => "1" })
  response = request :post, LOGIN_PATH, body: body, headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  (username, response.success?)
  response
end

#logout(session_token, headers: {}, **opts) ⇒ Parse::Response

Logout a user by deleting the associated session.

Parameters:

  • session_token (String)

    the Parse user session token to delete.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

  • opts (Hash)

    additional options to pass to the Client request.

Returns:



243
244
245
246
247
# File 'lib/parse/api/users.rb', line 243

def logout(session_token, headers: {}, **opts)
  headers.merge!({ Parse::Protocol::SESSION_TOKEN => session_token })
  opts.merge!({ use_master_key: false, session_token: session_token })
  request :post, LOGOUT_PATH, headers: headers, opts: opts
end

#request_email_verification(email, headers: {}, **opts) ⇒ Parse::Response

Request that Parse Server (re)send the email-address verification email for a registered, not-yet-verified user. Requires the server to have an email adapter and verifyUserEmails enabled; otherwise Parse Server responds with an error. Rate-limited per email like password reset.

Parameters:

  • email (String)

    the Parse user email.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



146
147
148
149
150
151
152
153
154
155
# File 'lib/parse/api/users.rb', line 146

def request_email_verification(email, headers: {}, **opts)
  rate_key = "emailverify:#{email}"
  (rate_key)
  body = { email: email }
  response = request :post, VERIFICATION_EMAIL_REQUEST, body: body, opts: opts, headers: headers
  # Indistinguishable found/not-found response, like password reset — count
  # every attempt toward backoff so probing can't reset the counter.
  (rate_key, false)
  response
end

#request_password_reset(email, headers: {}, **opts) ⇒ Parse::Response

Request a password reset for a registered email.

Client-side rate limited on a per-email basis using the same tracker that backs #login (entries are namespaced under a +pwreset:+ prefix so the two limiters don't collide on usernames that happen to equal an email). Every request counts toward the backoff — Parse Server's +requestPasswordReset+ response does not differentiate "email exists" from "email does not exist" (and rightly so, to avoid account enumeration), so the SDK cannot distinguish a legitimate retry from an attacker probing for valid emails. The cap mirrors LOGIN_MAX_FAILURES: 5 requests within the rolling window before exponential backoff kicks in and the limit clears via the same TTL-based cleanup.

Parameters:

  • email (String)

    the Parse user email.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:

Raises:

  • (RuntimeError)

    when the per-email request rate is exceeded.



123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/parse/api/users.rb', line 123

def request_password_reset(email, headers: {}, **opts)
  rate_key = "pwreset:#{email}"
  (rate_key)
  body = { email: email }
  response = request :post, REQUEST_PASSWORD_RESET, body: body, opts: opts, headers: headers
  # Always count the attempt as a "failure" for backoff purposes:
  # the response body is intentionally indistinguishable across
  # found/not-found emails, so we cannot reset the counter on
  # "success" without leaking that distinction to an attacker who
  # is probing.
  (rate_key, false)
  response
end

#set_service_auth_data(id, service_name, auth_data, headers: {}, **opts) ⇒ Parse::Response

Set the authentication service OAUth data for a user. Deleting or unlinking is done by setting the authData of the service name to nil.

Parameters:

  • id (String)

    the Parse user objectId.

  • service_name (Symbol)

    the name of the OAuth service.

  • auth_data (Hash)

    the hash data related to the third-party service.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



90
91
92
93
# File 'lib/parse/api/users.rb', line 90

def set_service_auth_data(id, service_name, auth_data, headers: {}, **opts)
  body = { authData: { service_name => auth_data } }
  update_user(id, body, headers: headers, **opts)
end

#signup(username, password, email = nil, body: {}, **opts) ⇒ Parse::Response

Signup a user given a username, password and, optionally, their email.

Parameters:

  • username (String)

    the Parse user username.

  • password (String)

    the Parse user's associated password.

  • email (String) (defaults to: nil)

    the desired Parse user's email.

  • body (Hash) (defaults to: {})

    additional property values to pass when creating the user record.

  • opts (Hash)

    additional options to pass to the Client request.

Returns:



256
257
258
259
260
# File 'lib/parse/api/users.rb', line 256

def (username, password, email = nil, body: {}, **opts)
  body = body.merge({ username: username, password: password })
  body[:email] = email || body[:email]
  create_user(body, **opts)
end

#update_user(id, body = {}, headers: {}, **opts) ⇒ Parse::Response

Update a User record given an objectId.

Parameters:

  • id (String)

    the Parse user objectId.

  • body (Hash) (defaults to: {})

    the body of the API request.

  • opts (Hash)

    additional options to pass to the Client request.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

Returns:



76
77
78
79
80
# File 'lib/parse/api/users.rb', line 76

def update_user(id, body = {}, headers: {}, **opts)
  response = request :put, "#{USER_PATH_PREFIX}/#{id}", body: body, headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  response
end

#verify_password(username, password, headers: {}, **opts) ⇒ Parse::Response

Verify a user's credentials against Parse Server without minting a session. This is the canonical step-up / re-authentication primitive: it confirms that the username + password combination is correct without producing a new session token on success.

Uses the +POST /parse/verifyPassword+ endpoint (credentials in the request BODY, mirroring +login+) rather than the +GET+ form. Parse Server accepts both (same handler, neither master-key gated; the POST variant landed in 7.1.0), but POST keeps the plaintext password out of the URL — and therefore out of server access logs, reverse-proxy logs, the +Referer+ header, and the SDK's URL-keyed response cache.

On success Parse Server returns the user object (HTTP 200) with the same shape as a login response (minus +sessionToken+). On failure it returns a 4xx with an error body, most commonly:

  • code 101 (+ERROR_OBJECT_NOT_FOUND+) for an unknown username or wrong password.
  • code 205 (+ERROR_EMAIL_NOT_FOUND+) when +preventLoginWithUnverifiedEmail+ is enabled and the account's email has not been verified.

Parameters:

  • username (String)

    the Parse user username.

  • password (String)

    the Parse user's associated password.

  • headers (Hash) (defaults to: {})

    additional HTTP headers to send with the request.

  • opts (Hash)

    additional options to pass to the Client request.

Returns:



231
232
233
234
235
236
# File 'lib/parse/api/users.rb', line 231

def verify_password(username, password, headers: {}, **opts)
  body = { username: username, password: password }
  response = request :post, VERIFY_PASSWORD_PATH, body: body, headers: headers, opts: opts
  response.parse_class = Parse::Model::CLASS_USER
  response
end