Module: Descope::Api::V1::Session

Includes:
Mixins::Common, Mixins::Common::EndpointsV1, Mixins::Common::EndpointsV2
Included in:
Descope::Api::V1
Defined in:
lib/descope/api/v1/session.rb

Overview

Holds all session methods

Constant Summary

Constants included from Mixins::Common::EndpointsV2

Mixins::Common::EndpointsV2::PUBLIC_KEY_PATH

Constants included from Mixins::Common::EndpointsV1

Mixins::Common::EndpointsV1::AUTH_SAML_START_PATH, Mixins::Common::EndpointsV1::EXCHANGE_AUTH_ACCESS_KEY_PATH, Mixins::Common::EndpointsV1::GET_SESSION_ENCHANTEDLINK_AUTH_PATH, Mixins::Common::EndpointsV1::GET_SESSION_MAGICLINK_AUTH_PATH, Mixins::Common::EndpointsV1::HISTORY_PATH, Mixins::Common::EndpointsV1::LOGOUT_ALL_PATH, Mixins::Common::EndpointsV1::LOGOUT_PATH, Mixins::Common::EndpointsV1::ME_PATH, Mixins::Common::EndpointsV1::OAUTH_CREATE_REDIRECT_URL_FOR_SIGN_IN_REQUEST_PATH, Mixins::Common::EndpointsV1::OAUTH_CREATE_REDIRECT_URL_FOR_SIGN_UP_REQUEST_PATH, Mixins::Common::EndpointsV1::OAUTH_EXCHANGE_TOKEN_PATH, Mixins::Common::EndpointsV1::OAUTH_START_PATH, Mixins::Common::EndpointsV1::PASSWORD_POLICY_PATH, Mixins::Common::EndpointsV1::REFRESH_TOKEN_PATH, Mixins::Common::EndpointsV1::REPLACE_PASSWORD_PATH, Mixins::Common::EndpointsV1::SAML_EXCHANGE_TOKEN_PATH, Mixins::Common::EndpointsV1::SELECT_TENANT_PATH, Mixins::Common::EndpointsV1::SEND_RESET_PASSWORD_PATH, Mixins::Common::EndpointsV1::SIGN_IN_AUTH_ENCHANTEDLINK_PATH, Mixins::Common::EndpointsV1::SIGN_IN_AUTH_MAGICLINK_PATH, Mixins::Common::EndpointsV1::SIGN_IN_AUTH_OTP_PATH, Mixins::Common::EndpointsV1::SIGN_IN_AUTH_WEBAUTHN_FINISH_PATH, Mixins::Common::EndpointsV1::SIGN_IN_AUTH_WEBAUTHN_START_PATH, Mixins::Common::EndpointsV1::SIGN_IN_PASSWORD_PATH, Mixins::Common::EndpointsV1::SIGN_UP_AUTH_ENCHANTEDLINK_PATH, Mixins::Common::EndpointsV1::SIGN_UP_AUTH_MAGICLINK_PATH, Mixins::Common::EndpointsV1::SIGN_UP_AUTH_OTP_PATH, Mixins::Common::EndpointsV1::SIGN_UP_AUTH_TOTP_PATH, Mixins::Common::EndpointsV1::SIGN_UP_AUTH_WEBAUTHN_FINISH_PATH, Mixins::Common::EndpointsV1::SIGN_UP_AUTH_WEBAUTHN_START_PATH, Mixins::Common::EndpointsV1::SIGN_UP_OR_IN_AUTH_ENCHANTEDLINK_PATH, Mixins::Common::EndpointsV1::SIGN_UP_OR_IN_AUTH_MAGICLINK_PATH, Mixins::Common::EndpointsV1::SIGN_UP_OR_IN_AUTH_OTP_PATH, Mixins::Common::EndpointsV1::SIGN_UP_OR_IN_AUTH_WEBAUTHN_START_PATH, Mixins::Common::EndpointsV1::SIGN_UP_PASSWORD_PATH, Mixins::Common::EndpointsV1::UPDATE_AUTH_WEBAUTHN_FINISH_PATH, Mixins::Common::EndpointsV1::UPDATE_AUTH_WEBAUTHN_START_PATH, Mixins::Common::EndpointsV1::UPDATE_PASSWORD_PATH, Mixins::Common::EndpointsV1::UPDATE_TOTP_PATH, Mixins::Common::EndpointsV1::UPDATE_USER_EMAIL_ENCHANTEDLINK_PATH, Mixins::Common::EndpointsV1::UPDATE_USER_EMAIL_MAGICLINK_PATH, Mixins::Common::EndpointsV1::UPDATE_USER_EMAIL_OTP_PATH, Mixins::Common::EndpointsV1::UPDATE_USER_PHONE_MAGICLINK_PATH, Mixins::Common::EndpointsV1::UPDATE_USER_PHONE_OTP_PATH, Mixins::Common::EndpointsV1::VALIDATE_SESSION_PATH, Mixins::Common::EndpointsV1::VERIFY_CODE_AUTH_PATH, Mixins::Common::EndpointsV1::VERIFY_ENCHANTEDLINK_AUTH_PATH, Mixins::Common::EndpointsV1::VERIFY_MAGICLINK_AUTH_PATH, Mixins::Common::EndpointsV1::VERIFY_TOTP_PATH

Constants included from Mixins::Common

Mixins::Common::COOKIE_DATA_NAME, Mixins::Common::DEFAULT_BASE_URL, Mixins::Common::DEFAULT_JWT_VALIDATION_LEEWAY, Mixins::Common::DEFAULT_TIMEOUT_SECONDS, Mixins::Common::PHONE_REGEX, Mixins::Common::REDIRECT_LOCATION_COOKIE_NAME, Mixins::Common::REFRESH_SESSION_COOKIE_NAME, Mixins::Common::REFRESH_SESSION_TOKEN_NAME, Mixins::Common::SESSION_COOKIE_NAME, Mixins::Common::SESSION_TOKEN_NAME

Instance Method Summary collapse

Methods included from Mixins::Common

#deep_copy, #get_method_string

Instance Method Details

#history(refresh_token = nil) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/descope/api/v1/session.rb', line 99

def history(refresh_token = nil)
  # Retrieve user authentication history for the refresh token
  # Return List in the format
  #              [
  #                 {
  #                     "userId": "User's ID",
  #                     "loginTime": "User'sLogin time",
  #                     "city": "User's city",
  #                     "country": "User's country",
  #                     "ip": User's IP
  #                 }
  #             ]
  validate_refresh_token_not_nil(refresh_token)
  get(HISTORY_PATH, {}, {}, refresh_token)
end

#me(refresh_token = nil) ⇒ Object



47
48
49
# File 'lib/descope/api/v1/session.rb', line 47

def me(refresh_token = nil)
  get(ME_PATH, {}, {}, refresh_token)
end

#refresh_session(refresh_token: nil, audience: nil) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/descope/api/v1/session.rb', line 16

def refresh_session(refresh_token: nil, audience: nil)
  #  Validate a session token. Call this function for every incoming request to your
  #  private endpoints. Alternatively, use validate_and_refresh_session in order to
  #  automatically refresh expired sessions. If you need to use these specific claims
  #  [amr, drn, exp, iss, rexp, sub, jwt] in the top level of the response dict, please use
  #  them from the sessionToken key instead, as these claims will soon be deprecated from the top level
  #  of the response dict.
  #  Make sure you set Enable refresh token rotation in the Project Settings before using this.
  validate_refresh_token_not_nil(refresh_token)
  validate_token(refresh_token, audience)
  res = post(REFRESH_TOKEN_PATH, {}, {}, refresh_token)
  cookies = res.fetch(COOKIE_DATA_NAME, nil) || res.fetch('cookies', {})
  
  # Check each source and use the first non-empty value
  refresh_cookie = nil
  cookie_value = cookies.fetch(REFRESH_SESSION_COOKIE_NAME, nil)
  if cookie_value && !cookie_value.empty?
    refresh_cookie = cookie_value
  else
    jwt_value = res.fetch('refreshJwt', nil)
    if jwt_value && !jwt_value.empty?
      refresh_cookie = jwt_value
    else
      refresh_cookie = refresh_token
    end
  end
  
  logger.debug("Refreshing refresh_cookie: #{refresh_cookie}")
  generate_jwt_response(response_body: res, refresh_cookie: refresh_cookie, audience: audience)
end

#sign_out(refresh_token = nil) ⇒ Object



51
52
53
# File 'lib/descope/api/v1/session.rb', line 51

def sign_out(refresh_token = nil)
  post(LOGOUT_PATH, {}, {}, refresh_token)
end

#sign_out_all(refresh_token = nil) ⇒ Object



55
56
57
# File 'lib/descope/api/v1/session.rb', line 55

def sign_out_all(refresh_token = nil)
  post(LOGOUT_ALL_PATH, {}, {}, refresh_token)
end

#token_validation_key(project_id) ⇒ Object



12
13
14
# File 'lib/descope/api/v1/session.rb', line 12

def token_validation_key(project_id)
  get("#{PUBLIC_KEY_PATH}/#{project_id}")
end

#validate_and_refresh_session(session_token: nil, refresh_token: nil, audience: nil) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/descope/api/v1/session.rb', line 82

def validate_and_refresh_session(session_token: nil, refresh_token: nil, audience: nil)
  # Validate the session token and refresh it if it has expired, the session token will automatically be refreshed.
  # Either the session_token or the refresh_token must be provided.
  # Call this function for every incoming request to your
  # private endpoints. Alternatively, use validate_session to only validate the session.

  raise Descope::AuthException.new('Session token is missing', code: 400) if session_token.nil?

  begin
    @logger.debug("Validating session token: #{session_token}")
    validate_session(session_token: session_token, audience: audience)
  rescue Descope::AuthException
    @logger.debug("Session is invalid, refreshing session with refresh token: #{refresh_token}")
    refresh_session(refresh_token: refresh_token, audience: audience)
  end
end

#validate_session(session_token: nil, audience: nil) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/descope/api/v1/session.rb', line 59

def validate_session(session_token: nil, audience: nil)
  # Validate a session token. Call this function for every incoming request to your
  # private endpoints. Alternatively, use validate_and_refresh_session in order to
  # automatically refresh expired sessions. If you need to use these specific claims
  # [amr, drn, exp, iss, rexp, sub, jwt] in the top level of the response dict, please use
  # them from the sessionToken key instead, as these claims will soon be deprecated from the top level
  # of the response dict.
  # Return a hash includes the session token and all JWT claims

  if session_token.nil? || session_token.empty?
    raise Descope::AuthException.new('Session token is required for validation', code: 400)
  end

  @logger.debug("Validating session token: #{session_token}")
  res = validate_token(session_token, audience)
  @logger.debug("Session token validation response: #{res}")
  # Duplicate for saving backward compatibility but keep the same structure as the refresh operation response
  res[SESSION_TOKEN_NAME] = deep_copy(res)
  session_props = adjust_properties(res, true)
  @logger.debug("session validation jwt response properties: #{session_props}")
  session_props
end