Commit 8c93fe7b authored by Yousef Sameh's avatar Yousef Sameh

deeplink and password reset

parent de16be72
using UnityEngine;
using System;
using UnityEngine.Events;
public sealed class DeepLinkManager : MonoBehaviour
{
public static DeepLinkManager Instance { get; private set; }
public string lastProcessedUrl;
public UnityEvent OnDeepLinkReceived;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
// 1. WARM START: Listen for links while the app is already running
Application.deepLinkActivated += OnDeepLinkActivated;
// 2. COLD START: Check if the app was opened via a link
if (!string.IsNullOrEmpty(Application.absoluteURL))
{
OnDeepLinkActivated(Application.absoluteURL);
}
}
else
{
Destroy(gameObject);
}
}
private void OnDeepLinkActivated(string url)
{
lastProcessedUrl = url;
Debug.Log($"[شارح] Deep Link Received: {url}");
// Logic to route the user
ProcessDeepLink(url);
}
private async void ProcessDeepLink(string url)
{
try
{
OnDeepLinkReceived?.Invoke();
Uri uri = new Uri(url);
// Check if it's our password reset host
if (uri.Host == "reset-password")
{
var resetSessionOrError = await SupabaseAuthentication.Instance.UpdateSessionFromURl(uri);
resetSessionOrError.Switch(
resetSession =>
{
},
error =>
{
Debug.LogError($"Failed to process password reset link: {error}");
}
);
}
}
catch (Exception ex)
{
Debug.LogError($"Deep Link Error: {ex.Message}");
}
}
}
fileFormatVersion: 2
guid: 55400cde731761ca3943099c02f27902
\ No newline at end of file
......@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using OneOf;
using Supabase.Gotrue;
using Supabase.Gotrue.Exceptions;
using UnityEngine;
......@@ -243,6 +244,108 @@ public class SupabaseAuthentication
}
}
public async UniTask<OneOf<Success, string>> UpdateSessionFromURl(Uri url)
{
try
{
var client = SupabaseManager.Instance.Supabase();
await client.Auth.GetSessionFromUrl(url);
return new Success();
}
catch (GotrueException ex)
{
Debug.LogError($"[Auth Delete] {ex.Message}");
return ex.Message;
}
catch (Exception ex)
{
// If the function returns a 400 or 500, it often lands here
Debug.LogError($"[Auth Delete] {ex.Message}");
return "Server error during deletion. Please try again later.";
}
finally
{
IsLoading = false;
}
}
public async UniTask<OneOf<Success, string>> UpdatePassword(string newPassword)
{
try
{
var client = SupabaseManager.Instance.Supabase();
await client.Auth.Update(
new UserAttributes
{
Password = newPassword
}
);
return new Success();
}
catch (GotrueException ex)
{
Debug.LogError($"[Auth Delete] {ex.Message}");
return ex.Message;
}
catch (Exception ex)
{
// If the function returns a 400 or 500, it often lands here
Debug.LogError($"[Auth Delete] {ex.Message}");
return "Server error during deletion. Please try again later.";
}
finally
{
IsLoading = false;
}
}
public async UniTask<OneOf<Success, string>> ResetPasswordRequest(string email)
{
try
{
var client = SupabaseManager.Instance.Supabase();
var options = new ResetPasswordForEmailOptions(email)
{
RedirectTo = "sharh://reset-password"
};
await client.Auth.ResetPasswordForEmail(options);
// client.Auth.GetSessionFromUrl("supabaseauth://callback#access_token);
//
// var atr = new UserAttributes
// {
// Password = "newpassword123"
// };
//
// await client.Auth.Update(atr);
return new Success();
}
catch (GotrueException ex)
{
Debug.LogError($"[Auth Delete] {ex.Message}");
return ex.Message;
}
catch (Exception ex)
{
// If the function returns a 400 or 500, it often lands here
Debug.LogError($"[Auth Delete] {ex.Message}");
return "Server error during deletion. Please try again later.";
}
finally
{
IsLoading = false;
}
}
public async UniTask<OneOf<Success, string>> DeleteAccount()
{
try
......@@ -274,8 +377,10 @@ public class SupabaseAuthentication
};
var options = new Supabase.Functions.Client.InvokeFunctionOptions();
options.Headers = headers;
var options = new Supabase.Functions.Client.InvokeFunctionOptions
{
Headers = headers
};
// 4. Call the Edge Function with explicit headers
// Pass 'null' for the body if you don't need to send extra data
await client.Functions.Invoke("delete-self", client.Auth.CurrentSession.AccessToken, options);
......
......@@ -380,51 +380,6 @@ Camera:
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!1 &1093642340
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1093642342}
- component: {fileID: 1093642341}
m_Layer: 0
m_Name: LoginController
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!114 &1093642341
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1093642340}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 15584a60abf537c4fb863ba3aeb3ee6d, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::LoginController
uIDocument: {fileID: 1971829438}
--- !u!4 &1093642342
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1093642340}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 95.29111, y: 1207.8973, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1311728067
GameObject:
m_ObjectHideFlags: 0
......@@ -549,6 +504,51 @@ MonoBehaviour:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!1 &1627471396
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1627471398}
- component: {fileID: 1627471397}
m_Layer: 0
m_Name: DeepLinkListener
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1627471397
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1627471396}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 55400cde731761ca3943099c02f27902, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::DeepLinkManager
lastProcessedUrl:
--- !u!4 &1627471398
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1627471396}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 13.23337, y: 10.52223, z: 0.38014}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1628372280
GameObject:
m_ObjectHideFlags: 0
......@@ -720,70 +720,10 @@ MonoBehaviour:
m_PivotReferenceSize: 0
m_Pivot: 0
m_WorldSpaceCollider: {fileID: 0}
--- !u!1 &2142479135
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2142479138}
- component: {fileID: 2142479137}
- component: {fileID: 2142479136}
m_Layer: 0
m_Name: SupabaseListener
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2142479136
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2142479135}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e8c8bd5f339c3203d84f2c7279a64eb0, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::SceneSwitcherHelpers
--- !u!114 &2142479137
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2142479135}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 14bbed8449713f51db869aa6dba9c6fa, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::SessionListener
splash: {fileID: 0}
LoginPageAnimation: {fileID: 545920731}
--- !u!4 &2142479138
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2142479135}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 616.9188, y: 1194.7426, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 1628372281}
- {fileID: 1093642342}
- {fileID: 2142479138}
- {fileID: 668896142}
- {fileID: 1627471398}
......@@ -150,6 +150,7 @@ public class LoginPageAnimation : MonoBehaviour
Button registerButton = loginPage.rootVisualElement.Q<Button>("RegisterButton");
registerButton.clicked += async () =>
{
registerButton.SetEnabled(false);
registerButton.text = "جاري التسجيل...";
......
fileFormatVersion: 2
guid: 5835013930be8e0f59b9e2cbd966db17
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="فتح شارح">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sharh" android:host="reset-password" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
<activity android:name="com.unity3d.player.UnityPlayerGameActivity"
android:theme="@style/BaseUnityGameActivityTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:label="فتح شارح">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sharh" android:host="reset-password" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="android.app.lib_name" android:value="game" />
</activity>
</application>
</manifest>
fileFormatVersion: 2
guid: 45f902060a0d727d2ab0d1f121f0e058
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment