Class: BetterAuth::Adapters::InternalAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/better_auth/adapters/internal_adapter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter, options) ⇒ InternalAdapter

Returns a new instance of InternalAdapter.



12
13
14
15
16
# File 'lib/better_auth/adapters/internal_adapter.rb', line 12

def initialize(adapter, options)
  @adapter = adapter
  @options = options
  @hooks = DatabaseHooks.new(adapter, options)
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter.



10
11
12
# File 'lib/better_auth/adapters/internal_adapter.rb', line 10

def adapter
  @adapter
end

#hooksObject (readonly)

Returns the value of attribute hooks.



10
11
12
# File 'lib/better_auth/adapters/internal_adapter.rb', line 10

def hooks
  @hooks
end

#optionsObject (readonly)

Returns the value of attribute options.



10
11
12
# File 'lib/better_auth/adapters/internal_adapter.rb', line 10

def options
  @options
end

Instance Method Details

#count_total_users(where: nil) ⇒ Object



57
58
59
# File 'lib/better_auth/adapters/internal_adapter.rb', line 57

def count_total_users(where: nil)
  adapter.count(model: "user", where: where || [])
end

#create_account(account) ⇒ Object



32
33
34
# File 'lib/better_auth/adapters/internal_adapter.rb', line 32

def ()
  hooks.create(timestamps.merge(stringify_keys()), "account")
end

#create_oauth_user(user, account) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/better_auth/adapters/internal_adapter.rb', line 18

def create_oauth_user(user, )
  adapter.transaction do
    created_user = create_user(user)
     = (stringify_keys().merge("userId" => created_user["id"]))
    {user: created_user, account: }
  end
end

#create_session(user_id, dont_remember_me = false, override = nil, override_all = false, context = nil) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/better_auth/adapters/internal_adapter.rb', line 70

def create_session(user_id, dont_remember_me = false, override = nil, override_all = false, context = nil)
  override = stringify_keys(override || {})
  token = override.delete("token") || SecureRandom.hex(16)
  base = {
    "ipAddress" => "",
    "userAgent" => "",
    "expiresAt" => Time.now + (dont_remember_me ? 86_400 : options.session[:expires_in].to_i),
    "userId" => user_id,
    "token" => token
  }.merge(timestamps)
  base["id"] = generated_id if secondary_storage
  data = override_all ? base.merge(override) : override.merge(base)

  custom = secondary_storage && lambda do |session_data|
    actual_session = apply_schema_create("session", session_data)
    store_session(actual_session)
    adapter.create(model: "session", data: actual_session, force_allow_id: true) if options.session[:store_session_in_database]
    actual_session
  end
  hooks.create(data, "session", custom: custom, context: context)
end

#create_user(user) ⇒ Object



26
27
28
29
30
# File 'lib/better_auth/adapters/internal_adapter.rb', line 26

def create_user(user)
  data = timestamps.merge(stringify_keys(user))
  data["email"] = data["email"].to_s.downcase if data["email"]
  hooks.create(data, "user")
end

#create_verification_value(data) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/better_auth/adapters/internal_adapter.rb', line 236

def create_verification_value(data)
  payload = timestamps.merge(stringify_keys(data))
  stored_identifier = processed_verification_identifier(payload.fetch("identifier"))
  payload["identifier"] = stored_identifier

  custom = secondary_storage && lambda do |verification_data|
    actual = apply_schema_create("verification", verification_data)
    actual["id"] ||= generated_id
    store_verification(actual)
    adapter.create(model: "verification", data: actual, force_allow_id: true) if verification_store_in_database?
    actual
  end

  hooks.create(payload, "verification", custom: custom)
end

#delete_account(account_id) ⇒ Object



166
167
168
# File 'lib/better_auth/adapters/internal_adapter.rb', line 166

def ()
  hooks.delete([{field: "id", value: }], "account")
end

#delete_accounts(user_id) ⇒ Object



162
163
164
# File 'lib/better_auth/adapters/internal_adapter.rb', line 162

def delete_accounts(user_id)
  hooks.delete_many([{field: "userId", value: user_id}], "account")
end

#delete_session(token) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/better_auth/adapters/internal_adapter.rb', line 131

def delete_session(token)
  if secondary_storage
    data = parse_storage(secondary_storage.get(token))
    if data && data["session"]
      user_id = data["session"]["userId"]
      entries = active_session_entries(user_id).reject { |entry| entry["token"] == token }
      write_active_sessions(user_id, entries)
    end
    secondary_storage.delete(token)
    return if !options.session[:store_session_in_database] || options.session[:preserve_session_in_database]
  end

  hooks.delete([{field: "token", value: token}], "session")
end

#delete_sessions(user_id_or_tokens) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/better_auth/adapters/internal_adapter.rb', line 146

def delete_sessions(user_id_or_tokens)
  if secondary_storage
    if user_id_or_tokens.is_a?(Array)
      user_id_or_tokens.each { |token| secondary_storage.delete(token) }
    else
      active_session_entries(user_id_or_tokens).each { |entry| secondary_storage.delete(entry["token"]) }
      secondary_storage.delete(active_key(user_id_or_tokens))
    end
    return if !options.session[:store_session_in_database] || options.session[:preserve_session_in_database]
  end

  field = user_id_or_tokens.is_a?(Array) ? "token" : "userId"
  operator = user_id_or_tokens.is_a?(Array) ? "in" : nil
  hooks.delete_many([{field: field, value: user_id_or_tokens, operator: operator}], "session")
end

#delete_user(user_id) ⇒ Object



61
62
63
64
65
66
67
68
# File 'lib/better_auth/adapters/internal_adapter.rb', line 61

def delete_user(user_id)
  deleted = hooks.delete([{field: "id", value: user_id}], "user")
  return false if deleted == false

  hooks.delete_many([{field: "userId", value: user_id}], "account")
  delete_sessions(user_id) if !secondary_storage || options.session[:store_session_in_database]
  deleted
end

#delete_verification_by_identifier(identifier) ⇒ Object



295
296
297
298
299
300
301
302
303
304
305
# File 'lib/better_auth/adapters/internal_adapter.rb', line 295

def delete_verification_by_identifier(identifier)
  stored_identifier = processed_verification_identifier(identifier)
  if secondary_storage
    cached = read_verification(stored_identifier)
    secondary_storage.delete(verification_key(stored_identifier))
    secondary_storage.delete(verification_id_key(cached["id"])) if cached && cached["id"]
    return nil unless verification_store_in_database?
  end

  hooks.delete([{field: "identifier", value: stored_identifier}], "verification")
end

#delete_verification_value(id) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/better_auth/adapters/internal_adapter.rb', line 280

def delete_verification_value(id)
  if secondary_storage
    stored_identifier = secondary_storage.get(verification_id_key(id))
    if stored_identifier
      secondary_storage.delete(verification_key(stored_identifier))
      secondary_storage.delete(verification_id_key(id))
      return nil unless verification_store_in_database?
    elsif !verification_store_in_database?
      return nil
    end
  end

  hooks.delete([{field: "id", value: id}], "verification")
end

#find_account(account_id) ⇒ Object



220
221
222
# File 'lib/better_auth/adapters/internal_adapter.rb', line 220

def ()
  adapter.find_one(model: "account", where: [{field: "accountId", value: }])
end

#find_account_by_provider_id(account_id, provider_id) ⇒ Object



224
225
226
# File 'lib/better_auth/adapters/internal_adapter.rb', line 224

def (, provider_id)
  adapter.find_one(model: "account", where: [{field: "accountId", value: }, {field: "providerId", value: provider_id}])
end

#find_account_by_user_id(user_id) ⇒ Object



228
229
230
# File 'lib/better_auth/adapters/internal_adapter.rb', line 228

def (user_id)
  find_accounts(user_id)
end

#find_accounts(user_id) ⇒ Object



216
217
218
# File 'lib/better_auth/adapters/internal_adapter.rb', line 216

def find_accounts(user_id)
  adapter.find_many(model: "account", where: [{field: "userId", value: user_id}])
end

#find_oauth_user(email, account_id, provider_id) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/better_auth/adapters/internal_adapter.rb', line 170

def find_oauth_user(email, , provider_id)
   = (, provider_id)
  if 
    user = ["user"] || adapter.find_one(model: "user", where: [{field: "email", value: email.to_s.downcase}])
    return nil unless user

    linked = .dup
    linked.delete("user")
    return {user: user, linked_account: linked, accounts: [linked]}
  end

  found_user = adapter.find_one(model: "user", where: [{field: "email", value: email.to_s.downcase}])
  return nil unless found_user

  {user: found_user, linked_account: nil, accounts: find_accounts(found_user["id"])}
end

#find_session(token) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/better_auth/adapters/internal_adapter.rb', line 92

def find_session(token)
  if secondary_storage
    data = parse_storage(secondary_storage.get(token))
    unless data
      return nil unless options.session[:store_session_in_database] && !options.session[:preserve_session_in_database]
    end

    if data
      return {
        session: normalize_session_dates(data["session"]),
        user: normalize_user_dates(data["user"])
      }
    end
  end

  found = find_session_with_user(token)
  return nil unless found && found["user"]

  user = found.delete("user")
  {session: found, user: user}
end

#find_sessions(tokens) ⇒ Object



114
115
116
# File 'lib/better_auth/adapters/internal_adapter.rb', line 114

def find_sessions(tokens)
  tokens.filter_map { |token| find_session(token) }
end

#find_user_by_email(email, include_accounts: false) ⇒ Object



187
188
189
190
191
192
# File 'lib/better_auth/adapters/internal_adapter.rb', line 187

def find_user_by_email(email, include_accounts: false)
  user = adapter.find_one(model: "user", where: [{field: "email", value: email.to_s.downcase}])
  return nil unless user

  {user: user, accounts: include_accounts ? find_accounts(user["id"]) : []}
end

#find_user_by_id(user_id) ⇒ Object



194
195
196
197
198
# File 'lib/better_auth/adapters/internal_adapter.rb', line 194

def find_user_by_id(user_id)
  return nil if user_id.to_s.empty?

  adapter.find_one(model: "user", where: [{field: "id", value: user_id}])
end

#find_verification_value(identifier) ⇒ Object



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/better_auth/adapters/internal_adapter.rb', line 252

def find_verification_value(identifier)
  stored_identifier = processed_verification_identifier(identifier)
  storage_option = verification_storage_option(identifier)
  if secondary_storage
    cached = read_verification(stored_identifier)
    cached ||= read_verification(identifier) if storage_option && storage_option.to_s != "plain"
    return cached if cached
    return nil unless verification_store_in_database?
  end

  values = adapter.find_many(
    model: "verification",
    where: [{field: "identifier", value: stored_identifier}],
    sort_by: {field: "createdAt", direction: "desc"},
    limit: 1
  )
  if values.empty? && storage_option && storage_option.to_s != "plain"
    values = adapter.find_many(
      model: "verification",
      where: [{field: "identifier", value: identifier}],
      sort_by: {field: "createdAt", direction: "desc"},
      limit: 1
    )
  end
  hooks.delete_many([{field: "expiresAt", value: Time.now, operator: "lt"}], "verification") unless options.verification[:disable_cleanup]
  values.first
end


36
37
38
# File 'lib/better_auth/adapters/internal_adapter.rb', line 36

def ()
  ()
end

#list_sessions(user_id) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/better_auth/adapters/internal_adapter.rb', line 40

def list_sessions(user_id)
  if secondary_storage
    active_session_entries(user_id).filter_map do |entry|
      data = parse_storage(secondary_storage.get(entry.fetch("token")))
      next unless data && data["session"]

      normalize_session_dates(data["session"])
    end
  else
    adapter.find_many(model: "session", where: [{field: "userId", value: user_id}])
  end
end

#list_users(limit: nil, offset: nil, sort_by: nil, where: nil) ⇒ Object



53
54
55
# File 'lib/better_auth/adapters/internal_adapter.rb', line 53

def list_users(limit: nil, offset: nil, sort_by: nil, where: nil)
  adapter.find_many(model: "user", where: where || [], limit: limit, offset: offset, sort_by: sort_by)
end

#update_account(id, data) ⇒ Object



232
233
234
# File 'lib/better_auth/adapters/internal_adapter.rb', line 232

def (id, data)
  hooks.update(stringify_keys(data), [{field: "id", value: id}], "account")
end

#update_password(user_id, password) ⇒ Object



212
213
214
# File 'lib/better_auth/adapters/internal_adapter.rb', line 212

def update_password(user_id, password)
  hooks.update_many({password: password}, [{field: "userId", value: user_id}, {field: "providerId", value: "credential"}], "account")
end

#update_session(token, session) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/better_auth/adapters/internal_adapter.rb', line 118

def update_session(token, session)
  data = stringify_keys(session)
  if secondary_storage
    return hooks.update(data, [{field: "token", value: token}], "session", custom: lambda { |actual_data|
      stored = update_stored_session(token, actual_data)
      db = adapter.update(model: "session", where: [{field: "token", value: token}], update: actual_data) if options.session[:store_session_in_database]
      db || stored
    })
  end

  hooks.update(data, [{field: "token", value: token}], "session")
end

#update_user(user_id, data) ⇒ Object



200
201
202
203
204
# File 'lib/better_auth/adapters/internal_adapter.rb', line 200

def update_user(user_id, data)
  user = hooks.update(stringify_keys(data), [{field: "id", value: user_id}], "user")
  refresh_user_sessions(user) if user
  user
end

#update_user_by_email(email, data) ⇒ Object



206
207
208
209
210
# File 'lib/better_auth/adapters/internal_adapter.rb', line 206

def update_user_by_email(email, data)
  user = hooks.update(stringify_keys(data), [{field: "email", value: email.to_s.downcase}], "user")
  refresh_user_sessions(user) if user
  user
end

#update_verification_value(id, data) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/better_auth/adapters/internal_adapter.rb', line 307

def update_verification_value(id, data)
  update = stringify_keys(data)
  if secondary_storage
    stored_identifier = secondary_storage.get(verification_id_key(id))
    if stored_identifier
      cached = read_verification(stored_identifier)
      if cached
        updated = cached.merge(update)
        store_verification(updated)
        return updated unless verification_store_in_database?
      end
    elsif !verification_store_in_database?
      return nil
    end
  end

  hooks.update(update, [{field: "id", value: id}], "verification")
end