# Email and Password Authentication

Allow users to sign up and sign in with their email address and a password in your Unity game. For passwordless authentication using one-time codes, see [Email OTP & SMS OTP](/docs/products/embedded-wallet/unity/auth/otp).

:::note
You can update the server sending email notifications and the email templates through your dashboard. Visit the guide on how to [update password authentication](/docs/configuration/password/custom-smtp) to learn more.
:::

## Methods

### SignUpWithEmailPassword

Creates a new user account with email and password.

**Method Signature:**

```csharp
public async UniTask<AuthResponse> SignUpWithEmailPassword(string email, string password, string name = null, string callbackURL = null)
```

**Parameters:**

* `string email` - User's email address
* `string password` - User's password
* `string name` - Optional display name for the user
* `string callbackURL` - Optional callback URL for email verification

**Returns:**

* `UniTask<AuthResponse>` - Authentication response containing user info and tokens. See [Authentication - Response types](/docs/products/embedded-wallet/authentication#response-types) for the full structure.

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class EmailSignUp : MonoBehaviour
{
    private OpenfortSDK openfort;
    
    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY" // Optional
        );
    }
    
    public async UniTask<AuthResponse> CreateNewAccount(string email, string password, string displayName = null)
    {
        try
        {
            var response = await openfort.SignUpWithEmailPassword(email, password, displayName);

            Debug.Log($"User created successfully: {response.User.Id}");
            Debug.Log($"Email: {response.User.Email}");
            Debug.Log($"Email verified: {response.User.EmailVerified}");

            return response;
        }
        catch (OpenfortException e)
        {
            Debug.LogError($"Signup failed: {e.Message}, Type: {e.Type}");
            throw;
        }
    }
}
```

### LogInWithEmailPassword

Authenticate an existing user with email and password.

**Method Signature:**

```csharp
public async UniTask<AuthResponse> LogInWithEmailPassword(string email, string password)
```

**Parameters:**

* `string email` - User's email address
* `string password` - User's password

**Returns:**

* `UniTask<AuthResponse>` - Authentication response containing user info and tokens

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class EmailLogin : MonoBehaviour
{
    private OpenfortSDK openfort;
    
    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );
    }
    
    public async UniTask<AuthResponse> LoginUser(string email, string password)
    {
        try
        {
            var response = await openfort.LogInWithEmailPassword(email, password);

            Debug.Log($"Login successful: {response.User.Id}");
            Debug.Log($"Email: {response.User.Email}");
            Debug.Log($"Session expires at: {response.Session?.ExpiresAt}");

            return response;
        }
        catch (OpenfortException e)
        {
            Debug.LogError($"Login failed: {e.Message}, Type: {e.Type}");
            throw;
        }
    }
}
```

### RequestEmailVerification

Send an email verification to the user.

**Method Signature:**

```csharp
public async UniTask RequestEmailVerification(RequestEmailVerificationRequest request)
```

**Parameters:**

* `RequestEmailVerificationRequest request` - Email verification request

**Returns:**

* `UniTask` - Completes when verification email is sent

**RequestEmailVerificationRequest Structure:**

```csharp
public class RequestEmailVerificationRequest
{
    public string email;       // User's email address
    public string redirectUrl; // URL to redirect after verification

    public RequestEmailVerificationRequest(string email, string redirectUrl)
    {
        this.email = email;
        this.redirectUrl = redirectUrl;
    }
}
```

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class EmailVerification : MonoBehaviour
{
    private OpenfortSDK openfort;
    
    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );
    }
    
    public async UniTask SendVerificationEmail(string email, string redirectUrl)
    {
        try
        {
            var request = new RequestEmailVerificationRequest(email, redirectUrl);

            await openfort.RequestEmailVerification(request);
            Debug.Log($"Verification email sent to {email}");
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to send verification email: {e.Message}");
            throw;
        }
    }
}
```

### VerifyEmail

Verify the user's email using the verification token from the email link.

**Method Signature:**

```csharp
public async UniTask VerifyEmail(VerifyEmailRequest request)
```

**Parameters:**

* `VerifyEmailRequest request` - Email verification request with token

**Returns:**

* `UniTask` - Completes when email is verified successfully

**VerifyEmailRequest Structure:**

```csharp
public class VerifyEmailRequest
{
    public string token;       // Verification token from email link
    public string callbackURL; // Optional callback URL

    public VerifyEmailRequest(string token, string callbackURL = null)
    {
        this.token = token;
        this.callbackURL = callbackURL;
    }
}
```

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class EmailVerifier : MonoBehaviour
{
    private OpenfortSDK openfort;

    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );
    }

    public async UniTask VerifyUserEmail(string verificationToken)
    {
        try
        {
            var request = new VerifyEmailRequest(verificationToken);

            await openfort.VerifyEmail(request);
            Debug.Log("Email verified successfully");
        }
        catch (Exception e)
        {
            Debug.LogError($"Email verification failed: {e.Message}");
            throw;
        }
    }
}
```

### RequestResetPassword

Request a password reset email for the user.

**Method Signature:**

```csharp
public async UniTask RequestResetPassword(ResetPasswordRequest request)
```

**Parameters:**

* `ResetPasswordRequest request` - Password reset request containing email

**Returns:**

* `UniTask` - Completes when reset email is sent

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class PasswordResetRequest : MonoBehaviour
{
    private OpenfortSDK openfort;
    
    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );
    }
    
    public async UniTask RequestPasswordReset(string password, string token)
    {
        try
        {
            var request = new ResetPasswordRequest(password, token);

            await openfort.RequestResetPassword(request);
            Debug.Log("Password reset request sent");
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to request password reset: {e.Message}");
            throw;
        }
    }
}
```

### ResetPassword

Reset the user's password using the verification token from email.

**Method Signature:**

```csharp
public async UniTask ResetPassword(ResetPasswordRequest request)
```

**Parameters:**

* `ResetPasswordRequest request` - Complete reset request with password and token

**Returns:**

* `UniTask` - Completes when password is reset successfully

**ResetPasswordRequest Structure:**

```csharp
public class ResetPasswordRequest
{
    public string password;  // New password
    public string token;     // Verification token from reset email

    public ResetPasswordRequest(string password, string token)
    {
        this.password = password;
        this.token = token;
    }
}
```

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class PasswordReset : MonoBehaviour
{
    private OpenfortSDK openfort;

    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );
    }

    public async UniTask ResetUserPassword(string newPassword, string verificationToken)
    {
        try
        {
            var request = new ResetPasswordRequest(newPassword, verificationToken);

            await openfort.ResetPassword(request);
            Debug.Log("Password reset successfully");
        }
        catch (Exception e)
        {
            Debug.LogError($"Password reset failed: {e.Message}");
            throw;
        }
    }
}
```

### Logout

Log out the current user and clear stored credentials.

**Method Signature:**

```csharp
public async UniTask Logout()
```

**Parameters:**

* None

**Returns:**

* `UniTask` - Completes when logout is finished

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;

public class UserLogout : MonoBehaviour
{
    private OpenfortSDK openfort;
    
    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );
    }
    
    public async UniTask LogoutUser()
    {
        try
        {
            await openfort.Logout();
            Debug.Log("User logged out successfully");
            
            // Navigate to login screen or perform cleanup
        }
        catch (Exception e)
        {
            Debug.LogError($"Logout failed: {e.Message}");
        }
    }
}
```

## UI integration example

Here's a basic example of how to integrate this with Unity UI:

```csharp
using TMPro;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;

public class AuthUIManager : MonoBehaviour
{
    [SerializeField] private TMP_InputField emailInput;
    [SerializeField] private TMP_InputField passwordInput;
    [SerializeField] private TMP_InputField nameInput; // Optional for signup
    [SerializeField] private Button signUpButton;
    [SerializeField] private Button loginButton;
    [SerializeField] private GameObject loadingIndicator;
    
    private OpenfortAuthManager authManager;

    private void Start()
    {
        authManager = GetComponent<OpenfortAuthManager>();
        
        signUpButton.onClick.AddListener(() => HandleSignUp().Forget());
        loginButton.onClick.AddListener(() => HandleLogin().Forget());
    }

    private async UniTaskVoid HandleSignUp()
    {
        SetUIEnabled(false);
        try
        {
            string name = string.IsNullOrEmpty(nameInput?.text) ? null : nameInput.text;
            await authManager.SignUpNewUser(emailInput.text, passwordInput.text, name);
            // Navigate to next scene or show success
        }
        catch (Exception e)
        {
            // Show error to user
            Debug.LogError($"Sign up failed: {e.Message}");
        }
        finally
        {
            SetUIEnabled(true);
        }
    }

    private async UniTaskVoid HandleLogin()
    {
        SetUIEnabled(false);
        try
        {
            var response = await authManager.LogInUser(emailInput.text, passwordInput.text);
            // Navigate to game scene
            Debug.Log($"Login successful for user: {response.User.Id}");
        }
        catch (Exception e)
        {
            // Show error to user
            Debug.LogError($"Login failed: {e.Message}");
        }
        finally
        {
            SetUIEnabled(true);
        }
    }

    private void SetUIEnabled(bool enabled)
    {
        signUpButton.interactable = enabled;
        loginButton.interactable = enabled;
        emailInput.interactable = enabled;
        passwordInput.interactable = enabled;
        if (loadingIndicator != null)
            loadingIndicator.SetActive(!enabled);
    }
}
```
