Skip to content
This repository was archived by the owner on Aug 18, 2024. It is now read-only.

Commit fc3574e

Browse files
committed
Added account recovery options.
1 parent e158bb6 commit fc3574e

File tree

5 files changed

+330
-17
lines changed

5 files changed

+330
-17
lines changed

Assets/Plugins/Lowscope/Appwrite/Runtime/Accounts/Account.cs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ namespace Lowscope.AppwritePlugin.Accounts
1515
{
1616
public class Account
1717
{
18-
public Action<User> OnLogin = delegate { };
19-
public Action OnLogout = delegate { };
18+
public Action<User> OnLogin = delegate { };
19+
public Action OnLogout = delegate { };
2020

2121
private readonly AppwriteConfig config;
2222
private readonly Dictionary<string, string> headers;
@@ -25,7 +25,7 @@ public class Account
2525
private DateTime lastRegisterRequestDate;
2626

2727
private bool validatedSession = false;
28-
28+
2929
private string UserPath => Path.Combine(Application.persistentDataPath, "user.json");
3030

3131
internal Account(AppwriteConfig config)
@@ -46,11 +46,11 @@ private void StoreUserToDisk()
4646
{
4747
FileUtilities.Write(user, UserPath, config);
4848

49-
if (validatedSession)
49+
if (validatedSession)
5050
return;
51-
51+
5252
validatedSession = true;
53-
53+
5454
OnLogin(user);
5555
}
5656

@@ -90,7 +90,7 @@ private async UniTask<bool> RequestUserInfo()
9090
ClearUserDataFromDisk();
9191
break;
9292
}
93-
93+
9494
return false;
9595
}
9696

@@ -142,7 +142,7 @@ or HttpStatusCode.InternalServerError
142142
or HttpStatusCode.TooManyRequests:
143143
return (null, ELoginResponse.ServerBusy);
144144
}
145-
145+
146146
Debug.Log($"Unimplemented: {httpStatusCode} {body}");
147147
return (null, ELoginResponse.Failed);
148148
}
@@ -173,7 +173,7 @@ or HttpStatusCode.InternalServerError
173173
{
174174
if (!WebUtilities.IsEmailValid(email))
175175
return (null, ERegisterResponse.InvalidEmail);
176-
176+
177177
if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(email))
178178
return (null, ERegisterResponse.MissingCredentials);
179179

@@ -215,7 +215,7 @@ or HttpStatusCode.InternalServerError
215215
return (null, ERegisterResponse.InvalidEmail);
216216
break;
217217
}
218-
218+
219219
Debug.Log($"Unimplemented: {httpStatusCode} {body}");
220220
return (null, ERegisterResponse.Failed);
221221
}
@@ -298,7 +298,7 @@ public async UniTask<EEmailVerifyResponse> RequestVerificationMail()
298298
string url = $"{config.AppwriteURL}/account/verification";
299299
using var request = new WebRequest(EWebRequestType.POST, url, headers, user.Cookie, bytes);
300300
var (json, httpStatusCode) = await request.Send();
301-
301+
302302
// Session has become invalid, not able to utilize session anymore.
303303
switch (httpStatusCode)
304304
{
@@ -314,6 +314,33 @@ public async UniTask<EEmailVerifyResponse> RequestVerificationMail()
314314
return httpStatusCode == HttpStatusCode.Created ? EEmailVerifyResponse.Sent : EEmailVerifyResponse.Failed;
315315
}
316316

317+
public async UniTask<EAccountRecoverResponse> RequestPasswordRecovery(string email)
318+
{
319+
if (!WebUtilities.IsEmailValid(email))
320+
return EAccountRecoverResponse.InvalidEmail;
321+
322+
if (user != null)
323+
return EAccountRecoverResponse.AlreadyLoggedIn;
324+
325+
JObject obj = new JObject(new JProperty("email", email), new JProperty("url", config.RecoverPasswordURL));
326+
byte[] bytes = Encoding.UTF8.GetBytes(obj.ToString());
327+
328+
string url = $"{config.AppwriteURL}/account/recovery";
329+
using var request = new WebRequest(EWebRequestType.POST, url, headers, "", bytes);
330+
var (json, httpStatusCode) = await request.Send();
331+
332+
switch (httpStatusCode)
333+
{
334+
case HttpStatusCode.Unauthorized:
335+
case HttpStatusCode.NotFound:
336+
return EAccountRecoverResponse.Failed;
337+
}
338+
339+
return httpStatusCode == HttpStatusCode.Created
340+
? EAccountRecoverResponse.Sent
341+
: EAccountRecoverResponse.Failed;
342+
}
343+
317344
/// <summary>
318345
/// Obtains user information
319346
/// </summary>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Lowscope.AppwritePlugin.Accounts.Enums
2+
{
3+
public enum EAccountRecoverResponse
4+
{
5+
AlreadyLoggedIn,
6+
Failed,
7+
Sent,
8+
InvalidEmail
9+
}
10+
}

Assets/Plugins/Lowscope/Appwrite/Runtime/AppwriteConfig.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public class AppwriteConfig : ScriptableObject
1111
public string AppwriteProjectID = "MyAppwriteProjectID";
1212

1313
[Header("Account")]
14-
public string VerifyEmailURL = "MyVerifyMailEndpoint";
14+
public string VerifyEmailURL = "https://myfrontendwebsitehere.com/verifymail";
15+
public string RecoverPasswordURL = "https://myfrontendwebsitehere.com/recover";
1516

1617
public float JwtExpireMinutes = 15;
1718
public float VerifyEmailTimeoutMinutes = 5;

Assets/Plugins/Lowscope/Appwrite/Samples/LoginRegisterMenu/AppwriteExampleUI.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Lowscope.AppwritePlugin.Accounts.Model;
66
using TMPro;
77
using UnityEngine;
8+
using UnityEngine.Serialization;
89
using UnityEngine.UI;
910

1011
public class AppwriteExampleUI : MonoBehaviour
@@ -21,6 +22,7 @@ public class AppwriteExampleUI : MonoBehaviour
2122
[SerializeField] private Button buttonRefreshInfo;
2223
[SerializeField] private Button buttonRegister;
2324
[SerializeField] private Button buttonVerifyMail;
25+
[SerializeField] private Button buttonRecoverAccount;
2426

2527
[SerializeField] private TextMeshProUGUI infoText;
2628

@@ -34,11 +36,25 @@ private async void Start()
3436
buttonRefreshInfo.onClick.AddListener(OnButtonRefreshInfo);
3537
buttonVerifyMail.onClick.AddListener(OnButtonVerifyMail);
3638
buttonRegister.onClick.AddListener(OnButtonRegister);
37-
39+
buttonRecoverAccount.onClick.AddListener(OnButtonRecoverAccount);
40+
inputFieldEmail.onValueChanged.AddListener(OnChangedEmailValue);
41+
3842
// Attempts to get/validate (saved) information from server
3943
await UpdateInfo(true);
4044
}
4145

46+
private void OnChangedEmailValue(string email)
47+
{
48+
buttonRecoverAccount.interactable = !string.IsNullOrEmpty(email);
49+
}
50+
51+
private async void OnButtonRecoverAccount()
52+
{
53+
string email = inputFieldEmail.text;
54+
var response = await Appwrite.Account.RequestPasswordRecovery(email);
55+
Debug.Log($"Email recovery. Response: {response}");
56+
}
57+
4258
private async void OnButtonLogin()
4359
{
4460
string email = inputFieldEmail.text;
@@ -60,7 +76,7 @@ private async void OnButtonLogout()
6076
bool hasLoggedOut = await Appwrite.Account.Logout();
6177
Debug.Log(!hasLoggedOut ? "Unable to logout. No session active." : "User logged out. Cookies cleared.");
6278
user = null;
63-
79+
6480
await UpdateInfo(false);
6581
}
6682

@@ -104,7 +120,7 @@ private async UniTask UpdateInfo(bool refreshFromServer)
104120
user = await Appwrite.Account.GetUser(true);
105121

106122
bool hasUser = user != null;
107-
123+
108124
if (hasUser)
109125
{
110126
StringBuilder sb = new StringBuilder();

0 commit comments

Comments
 (0)