Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 44 additions & 23 deletions lib/workos/user_management.ex
Original file line number Diff line number Diff line change
Expand Up @@ -134,28 +134,37 @@ defmodule WorkOS.UserManagement do
Parameter options:

* `:email` - The email address of the user. (required)
* `:domains` - The password to set for the user.
* `:password` - The password to set for the user.
* `:password_hash` - The hashed password to set for the user. Mutually exclusive with `password`.
* `:password_hash_type` - The algorithm originally used to hash the password. Valid values are `bcrypt`, `scrypt`, `firebase-scrypt`, `ssha`, `pbkdf2`, and `argon2`.
* `:first_name` - The user's first name.
* `:last_name` - The user's last name.
* `:email_verified` - Whether the user's email address was previously verified.
* `:external_id` - The external identifier of the user.
* `:metadata` - Object containing metadata key/value pairs associated with the user.

"""
@spec create_user(map()) :: WorkOS.Client.response(User.t())
@spec create_user(WorkOS.Client.t(), map()) ::
WorkOS.Client.response(User.t())
def create_user(client \\ WorkOS.client(), opts) when is_map_key(opts, :email) do
WorkOS.Client.post(
client,
User,
"/user_management/users",
%{
email: opts[:email],
domains: opts[:domains],
first_name: opts[:first_name],
last_name: opts[:last_name],
email_verified: opts[:email_verified]
}
)
body =
Map.take(
opts,
[
:email,
:password,
:password_hash,
:password_hash_type,
:first_name,
:last_name,
:email_verified,
:external_id,
:metadata
]
)

WorkOS.Client.post(client, User, "/user_management/users", body)
end

@doc """
Expand All @@ -165,24 +174,36 @@ defmodule WorkOS.UserManagement do

* `:first_name` - The user's first name.
* `:last_name` - The user's last name.
* `:email` - The user's email address. Changing a user's email will set `email_verified` to false.
* `:email_verified` - Whether the user's email address was previously verified.
* `:password` - The password to set for the user.
* `:password_hash` - The hashed password to set for the user, used when migrating from another user store. Mutually exclusive with password.
* `:password_hash_type` - The algorithm originally used to hash the password, used when providing a password_hash. Valid values are `bcrypt`.
* `:password_hash` - The hashed password to set for the user. Mutually exclusive with `password`.
* `:password_hash_type` - The algorithm originally used to hash the password. Valid values are `bcrypt`, `scrypt`, `firebase-scrypt`, `ssha`, `pbkdf2`, and `argon2`.
* `:external_id` - The external identifier of the user.
* `:metadata` - Object containing metadata key/value pairs associated with the user.

"""
@spec update_user(String.t(), map()) :: WorkOS.Client.response(User.t())
@spec update_user(WorkOS.Client.t(), String.t(), map()) ::
WorkOS.Client.response(User.t())
def update_user(client \\ WorkOS.client(), user_id, opts) do
WorkOS.Client.put(client, User, "/user_management/users/#{user_id}", %{
first_name: opts[:first_name],
last_name: opts[:last_name],
email_verified: !!opts[:email_verified],
password: opts[:password],
password_hash: opts[:password_hash],
password_hash_type: opts[:password_hash_type]
})
body =
Map.take(
opts,
[
:first_name,
:last_name,
:email,
:email_verified,
:password,
:password_hash,
:password_hash_type,
:external_id,
:metadata
]
)

WorkOS.Client.put(client, User, "/user_management/users/#{user_id}", body)
end

@doc """
Expand Down
103 changes: 103 additions & 0 deletions test/workos/user_management_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,51 @@ defmodule WorkOS.UserManagementTest do

refute is_nil(id)
end

test "with password, creates a user", context do
opts = [email: "test@example.com", password: "secure-password-123"]

context |> ClientMock.create_user(assert_fields: opts)

assert {:ok, %WorkOS.UserManagement.User{id: id}} =
WorkOS.UserManagement.create_user(opts |> Enum.into(%{}))

refute is_nil(id)
end

test "with password_hash, creates a user", context do
opts = [
email: "test@example.com",
password_hash: "$2a$10$abc123hashedpassword",
password_hash_type: "bcrypt"
]

context |> ClientMock.create_user(assert_fields: opts)

assert {:ok, %WorkOS.UserManagement.User{id: id}} =
WorkOS.UserManagement.create_user(opts |> Enum.into(%{}))

refute is_nil(id)
end

test "with all optional fields, creates a user", context do
opts = [
email: "test@example.com",
password: "secure-password-123",
first_name: "Test",
last_name: "User",
email_verified: true,
external_id: "ext_123",
metadata: %{"role" => "admin"}
]

context |> ClientMock.create_user(assert_fields: opts)

assert {:ok, %WorkOS.UserManagement.User{id: id}} =
WorkOS.UserManagement.create_user(opts |> Enum.into(%{}))

refute is_nil(id)
end
end

describe "update_user" do
Expand All @@ -193,6 +238,64 @@ defmodule WorkOS.UserManagementTest do

refute is_nil(id)
end

test "with email, updates a user", context do
opts = [
user_id: "user_01H5JQDV7R7ATEYZDEG0W5PRYS",
email: "newemail@example.com"
]

context |> ClientMock.update_user(assert_fields: opts)

assert {:ok, %WorkOS.UserManagement.User{id: id}} =
WorkOS.UserManagement.update_user(
opts |> Keyword.get(:user_id),
opts |> Enum.into(%{})
)

refute is_nil(id)
end

test "with password_hash, updates a user", context do
opts = [
user_id: "user_01H5JQDV7R7ATEYZDEG0W5PRYS",
password_hash: "$2a$10$abc123hashedpassword",
password_hash_type: "bcrypt"
]

context |> ClientMock.update_user(assert_fields: opts)

assert {:ok, %WorkOS.UserManagement.User{id: id}} =
WorkOS.UserManagement.update_user(
opts |> Keyword.get(:user_id),
opts |> Enum.into(%{})
)

refute is_nil(id)
end

test "with all optional fields, updates a user", context do
opts = [
user_id: "user_01H5JQDV7R7ATEYZDEG0W5PRYS",
first_name: "Test",
last_name: "User",
email: "updated@example.com",
email_verified: true,
password: "new-password-123",
external_id: "ext_456",
metadata: %{"role" => "user"}
]

context |> ClientMock.update_user(assert_fields: opts)

assert {:ok, %WorkOS.UserManagement.User{id: id}} =
WorkOS.UserManagement.update_user(
opts |> Keyword.get(:user_id),
opts |> Enum.into(%{})
)

refute is_nil(id)
end
end

describe "delete_user" do
Expand Down
Loading