diff --git a/Gotrue/Api.cs b/Gotrue/Api.cs index 597d10b..8d6d85e 100644 --- a/Gotrue/Api.cs +++ b/Gotrue/Api.cs @@ -55,6 +55,7 @@ public Api(string url, Dictionary? headers = null) _headers = headers; } + /// /// Signs a user up using an email address and password. /// @@ -99,7 +100,61 @@ public Api(string url, Dictionary? headers = null) } return null; } - + + + /// + /// Logs in an existing user using their email address. + /// + /// + /// + /// + public Task SignInWithEmail(UserAttributes attributes, SignUpOptions options = null) + { + string endpoint = $"{Url}/token?grant_type=password"; + + if (options != null) + { + if (!string.IsNullOrEmpty(options.RedirectTo)) + { + endpoint = Helpers.AddQueryParams(endpoint, new Dictionary { { "redirect_to", options.RedirectTo } }).ToString(); + } + + if (options.Data != null) + { + attributes.Data.Add("data", options.Data); + } + } + return Helpers.MakeRequest(HttpMethod.Post, endpoint, attributes, Headers); + } + + /// + /// Signs up a new user using their phone number and a password.The phone number of the user. + /// + /// The phone number of the user. + /// The password of the user. + /// Optional Signup data. + /// + public Task SignUpWithPhone(UserAttributes attributes, SignUpOptions options = null) + { + + string endpoint = $"{Url}/signup"; + + if (options != null) + { + if (!string.IsNullOrEmpty(options.RedirectTo)) + { + endpoint = Helpers.AddQueryParams(endpoint, new Dictionary { { "redirect_to", options.RedirectTo } }).ToString(); + } + + if (options.Data != null) + { + attributes.Data.Add("data", options.Data); + } + } + + return Helpers.MakeRequest(HttpMethod.Post, endpoint, attributes, Headers); + } + /// /// Logs in an existing user using their email address. /// diff --git a/Gotrue/Client.cs b/Gotrue/Client.cs index 2a8946f..443f71e 100644 --- a/Gotrue/Client.cs +++ b/Gotrue/Client.cs @@ -181,6 +181,70 @@ public void ClearStateChangedListeners() return session; } + + /// + /// Signs up a user by email address + /// + /// + /// + /// Object containing redirectTo and optional user metadata (data) + /// + public Task SignUp(string email, string password, SignUpOptions options = null) => SignUp(SignUpType.Email, email, password, options); + + public async Task SignUp(SignUpType type, UserAttributes attributes, SignUpOptions options = null) + { + await DestroySession(); + + try + { + Session session = null; + switch (type) + { + case SignUpType.Email: + session = await api.SignUpWithEmail(attributes, options); + break; + case SignUpType.Phone: + session = await api.SignUpWithPhone(attributes, options); + break; + } + + if (session?.User?.ConfirmedAt != null || (session.User != null && Options.AllowUnconfirmedUserSessions)) + { + await PersistSession(session); + + StateChanged?.Invoke(this, new ClientStateChanged(AuthState.SignedIn)); + + return CurrentSession; + } + + return session; + } + catch (RequestException ex) + { + Session session = null; + if (ex.Response.StatusCode == System.Net.HttpStatusCode.UnprocessableEntity) + { + switch (type) + { + case SignUpType.Email: + session = await api.SignInWithEmail(attributes); + break; + case SignUpType.Phone: + session = await api.SignUpWithPhone(attributes, options); + break; + } + + if (session?.User?.ConfirmedAt != null || (session.User != null && Options.AllowUnconfirmedUserSessions)) + { + await PersistSession(session); + StateChanged?.Invoke(this, new ClientStateChanged(AuthState.SignedIn)); + return CurrentSession; + } + } + return session; + } + } + /// public async Task SignIn(string email, SignInOptions? options = null) {