diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Models/StoreApiResponse.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Models/StoreApiResponse.cs index 50d56b202..71fd3253d 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Models/StoreApiResponse.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Models/StoreApiResponse.cs @@ -2,8 +2,7 @@ using System.Collections.Generic; using UnityEngine; -public class StoreApiResponse -{ +public class StoreApiResponse { public string message { get; set; } public bool success { get; set; } } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Web3AuthApi.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Web3AuthApi.cs index fe23c07d9..aaf4afea6 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Web3AuthApi.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Api/Web3AuthApi.cs @@ -19,9 +19,22 @@ public static Web3AuthApi getInstance() public IEnumerator authorizeSession(string key, Action callback) { - var request = UnityWebRequest.Get($"{baseAddress}/store/get?key={key}"); - yield return request.SendWebRequest(); + //var requestURL = $"{baseAddress}/store/get?key={key}"; + //var request = UnityWebRequest.Get(requestURL); + WWWForm data = new WWWForm(); + data.AddField("key", key); + + var request = UnityWebRequest.Post($"{baseAddress}/store/get", data); + yield return request.SendWebRequest(); + // Debug.Log("baseAddress =>" + baseAddress); + // Debug.Log("key =>" + key); + // //Debug.Log("request URL =>"+ requestURL); + // Debug.Log("request.isNetworkError =>" + request.isNetworkError); + // Debug.Log("request.isHttpError =>" + request.isHttpError); + // Debug.Log("request.isHttpError =>" + request.error); + // Debug.Log("request.result =>" + request.result); + // Debug.Log("request.downloadHandler.text =>" + request.downloadHandler.text); if (request.result == UnityWebRequest.Result.Success) { string result = request.downloadHandler.text; @@ -38,7 +51,37 @@ public IEnumerator logout(LogoutApiRequest logoutApiRequest, Action cal data.AddField("data", logoutApiRequest.data); data.AddField("signature", logoutApiRequest.signature); data.AddField("timeout", logoutApiRequest.timeout.ToString()); + // Debug.Log("key during logout session =>" + logoutApiRequest.key); + + var request = UnityWebRequest.Post($"{baseAddress}/store/set", data); + yield return request.SendWebRequest(); + + // Debug.Log("baseAddress =>" + baseAddress); + // Debug.Log("key =>" + logoutApiRequest.key); + // Debug.Log("request URL =>"+ requestURL); + // Debug.Log("request.isNetworkError =>" + request.isNetworkError); + // Debug.Log("request.isHttpError =>" + request.isHttpError); + // Debug.Log("request.isHttpError =>" + request.error); + // Debug.Log("request.result =>" + request.result); + // Debug.Log("request.downloadHandler.text =>" + request.downloadHandler.text); + if (request.result == UnityWebRequest.Result.Success) + { + string result = request.downloadHandler.text; + callback(Newtonsoft.Json.JsonConvert.DeserializeObject(result)); + } + else + callback(null); + } + + public IEnumerator createSession(LogoutApiRequest logoutApiRequest, Action callback) + { + WWWForm data = new WWWForm(); + data.AddField("key", logoutApiRequest.key); + data.AddField("data", logoutApiRequest.data); + data.AddField("signature", logoutApiRequest.signature); + data.AddField("timeout", logoutApiRequest.timeout.ToString()); + // Debug.Log("key during create session =>" + logoutApiRequest.key); var request = UnityWebRequest.Post($"{baseAddress}/store/set", data); yield return request.SendWebRequest(); diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Debug/Web3AuthDebug.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Debug/Web3AuthDebug.cs index e36bb1604..c6ce4a646 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Debug/Web3AuthDebug.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Debug/Web3AuthDebug.cs @@ -15,7 +15,7 @@ public class Web3AuthDebug : EditorWindow [SerializeField] public int index; - [MenuItem("Window/ChainSafe SDK/Web3Auth/Deep Linking Debug")] + [MenuItem("Window/Web3Auth/Deep Linking Debug")] public static void ShowExample() { Web3AuthDebug wnd = GetWindow(); diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Keystore/KeyStoreManagerUtils.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Keystore/KeyStoreManagerUtils.cs index 656e527ab..6f7be4f5a 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Keystore/KeyStoreManagerUtils.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Keystore/KeyStoreManagerUtils.cs @@ -6,6 +6,10 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities.Encoders; using System.Runtime.InteropServices; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Crypto; +using System.Text; public class KeyStoreManagerUtils { @@ -36,8 +40,7 @@ public static string getPubKey(string sessionId) var q = new ECPublicKeyParameters("EC", domain.G.Multiply(key.D), parameters).Q; return Hex.ToHexString(domain.Curve.CreatePoint(q.XCoord.ToBigInteger(), q.YCoord.ToBigInteger()).GetEncoded(false)); - } - catch (System.Exception ex) + } catch (System.Exception ex) { UnityEngine.Debug.Log(ex); return ""; @@ -77,8 +80,37 @@ public static void deletePreferencesData(string key) #endif } - public static string getECDSASignature(string privateKey, string data) + public static AsymmetricCipherKeyPair generateECKeyPair() + { + var secureRandom = new SecureRandom(); + var curve = SecNamedCurves.GetByName("secp256k1"); + var domainParams = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed()); + + var keyGenParam = new ECKeyGenerationParameters(domainParams, secureRandom); + var generator = GeneratorUtilities.GetKeyPairGenerator("ECDSA"); + generator.Init(keyGenParam); + + return generator.GenerateKeyPair(); + } + + public static string generateRandomSessionKey() { + var keyPair = generateECKeyPair(); + var privateKey = (ECPrivateKeyParameters)keyPair.Private; + var publicKey = (ECPublicKeyParameters)keyPair.Public; + + string privateKeyHex = privateKey.D.ToString(16).PadLeft(64, '0'); + return privateKeyHex; + } + + public static byte[] generateRandomBytes() { + var secureRandom = new SecureRandom(); + byte[] bytes = new byte[16]; + secureRandom.NextBytes(bytes); + return bytes; + } + + public static string getECDSASignature(string privateKey, string data){ var curve = SecNamedCurves.GetByName("secp256k1"); var domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); var keyParameters = new ECPrivateKeyParameters(new BigInteger(privateKey, 16), domain); @@ -110,4 +142,15 @@ public static string getECDSASignature(string privateKey, string data) return Hex.ToHexString(derSignature); } + + public static string convertByteToHexadecimal(byte[] byteArray) + { + string hex = ""; + // Iterating through each byte in the array + foreach (byte b in byteArray) + { + hex += $"{b:X2}"; + } + return hex.ToLowerInvariant(); + } } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/LoginVerifier.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/LoginVerifier.cs index 34f05f5d1..d2a7cd804 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/LoginVerifier.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/LoginVerifier.cs @@ -1,5 +1,4 @@ -public class LoginVerifier -{ +public class LoginVerifier { public string name { get; set; } public Provider loginProvider { get; set; } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.cs index 5a601246f..00539df76 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.cs @@ -46,7 +46,7 @@ void Start() { verifier = "your_verifierid_from_web3auth_dashboard", typeOfLogin = TypeOfLogin.GOOGLE, - clientId = "your_clientid_from_google_or_etc" + clientId = "your_clientId_from_web3auth_dashboard" }; web3Auth = GetComponent(); @@ -54,11 +54,11 @@ void Start() { whiteLabel = new WhiteLabelData() { - name = "Web3Auth Sample App", + appName = "Web3Auth Sample App", logoLight = null, logoDark = null, - defaultLanguage = "en", - dark = true, + defaultLanguage = Language.en, + mode = ThemeModes.dark, theme = new Dictionary { { "primary", "#123456" } @@ -72,7 +72,10 @@ void Start() {"CUSTOM_VERIFIER", loginConfigItem} } */ - network = Web3Auth.Network.TESTNET + clientId = "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ", + buildEnv = BuildEnv.PRODUCTION, + redirectUrl = new Uri("torusapp://com.torus.Web3AuthUnity/auth"), + network = Web3Auth.Network.SAPPHIRE_MAINNET }); web3Auth.onLogin += onLogin; web3Auth.onLogout += onLogout; diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.unity b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.unity index 982df5680..f68e52059 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.unity +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Samples/Web3AuthSample.unity @@ -896,9 +896,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 3eab2a0bf902d6e4b9c2e968ad89f528, type: 3} m_Name: m_EditorClassIdentifier: - clientId: BJ6l3_kIQiy6YVL7zDlCcEAvGpGukwFgp-C_0WvNI_fAEeIaoVRLDrV5OjtbZr_zJxbyXFsXMT-yhQiUNYvZWpo + clientId: BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ redirectUri: torusapp://com.torus.Web3AuthUnity/auth - network: 1 + network: 5 --- !u!1 &529774071 GameObject: m_ObjectHideFlags: 0 diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/AES256CBC.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/AES256CBC.cs index 431732cf1..1b2f6aed7 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/AES256CBC.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/AES256CBC.cs @@ -4,6 +4,9 @@ using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using System.Security.Cryptography; +using System.IO; +using System; +using System.Text; public class AES256CBC { @@ -11,6 +14,9 @@ public class AES256CBC private byte[] AES_ENCRYPTION_KEY; private byte[] ENCRYPTION_IV; + private byte[] MAC_KEY; + private byte[] ENCRYPTION_EPHEM_KEY; + public AES256CBC(string privateKeyHex, string ephemPublicKeyHex, string encryptionIvHex) { using (SHA512 shaM = new SHA512Managed()) @@ -24,12 +30,16 @@ public AES256CBC(string privateKeyHex, string ephemPublicKeyHex, string encrypti System.Array.Copy(hash, encKeyBytes, 32); AES_ENCRYPTION_KEY = encKeyBytes; - ENCRYPTION_IV = toByteArray(encryptionIvHex); + MAC_KEY = new byte[hash.Length - 32]; + System.Array.Copy(hash, 32, MAC_KEY, 0, MAC_KEY.Length); + + ENCRYPTION_IV = toByteArray(encryptionIvHex); + ENCRYPTION_EPHEM_KEY = toByteArray(ephemPublicKeyHex); } } - public string encrypt(byte[] src) + public byte[] encrypt(byte[] src) { var key = ParameterUtilities.CreateKeyParameter("AES", AES_ENCRYPTION_KEY); var parametersWithIv = new ParametersWithIV(key, ENCRYPTION_IV); @@ -37,22 +47,22 @@ public string encrypt(byte[] src) var cipher = CipherUtilities.GetCipher(TRANSFORMATION); cipher.Init(true, parametersWithIv); - return System.Text.Encoding.UTF8.GetString( - cipher.DoFinal(src) - ); + return cipher.DoFinal(src); } - public string decrypt(byte[] src) + public byte[] decrypt(byte[] src, string mac) { + if (!hmacSha256Verify(MAC_KEY, getCombinedData(src), mac)) + { + throw new SystemException("Bad MAC error during decrypt"); + } var key = ParameterUtilities.CreateKeyParameter("AES", AES_ENCRYPTION_KEY); var parametersWithIv = new ParametersWithIV(key, ENCRYPTION_IV); var cipher = CipherUtilities.GetCipher(TRANSFORMATION); cipher.Init(false, parametersWithIv); - return System.Text.Encoding.UTF8.GetString( - cipher.DoFinal(src) - ); + return cipher.DoFinal(src); } @@ -97,4 +107,35 @@ public static byte[] toByteArray(BigInteger bi) } return b; } + + public byte[] getCombinedData(byte[] cipherTextBytes) + { + using (MemoryStream outputStream = new MemoryStream()) + { + outputStream.Write(ENCRYPTION_IV, 0, ENCRYPTION_IV.Length); + outputStream.Write(ENCRYPTION_EPHEM_KEY, 0, ENCRYPTION_EPHEM_KEY.Length); + outputStream.Write(cipherTextBytes, 0, cipherTextBytes.Length); + return outputStream.ToArray(); + } + } + + public byte[] getMac(byte[] cipherTextBytes) + { + return hmacSha256Sign(MAC_KEY, getCombinedData(cipherTextBytes)); + } + + public byte[] hmacSha256Sign(byte[] key, byte[] data) + { + using (HMACSHA256 hmac = new HMACSHA256(key)) + { + return hmac.ComputeHash(data); + } + } + + public bool hmacSha256Verify(byte[] key, byte[] data, string sig) + { + byte[] expectedSig = hmacSha256Sign(key, data); + string expectedSigHex = BitConverter.ToString(expectedSig).Replace("-", "").ToLower(); + return expectedSigHex.Equals(sig); + } } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ExtraLoginOptions.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ExtraLoginOptions.cs index d89f997d3..65dfe5dcc 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ExtraLoginOptions.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ExtraLoginOptions.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; -public class ExtraLoginOptions -{ +public class ExtraLoginOptions { public Dictionary additionalParams { get; set; } public string domain { get; set; } public string client_id { get; set; } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/LoginConfigItem.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/LoginConfigItem.cs index 21072a250..0f3ec1837 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/LoginConfigItem.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/LoginConfigItem.cs @@ -1,5 +1,4 @@ -public class LoginConfigItem -{ +public class LoginConfigItem { public string verifier { get; set; } public TypeOfLogin typeOfLogin { get; set; } public string name { get; set; } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSetting.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSetting.cs new file mode 100644 index 000000000..f004a28f4 --- /dev/null +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSetting.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +#nullable enable +public class MfaSetting +{ + public bool enable { get; set; } + public int? priority { get; set; } + public bool? mandatory { get; set; } + + // Constructor + public MfaSetting(bool enable, int? priority, bool? mandatory) + { + this.enable = enable; + this.priority = priority; + this.mandatory = mandatory; + } +} \ No newline at end of file diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSetting.cs.meta b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSetting.cs.meta new file mode 100644 index 000000000..b7bedfc5a --- /dev/null +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSetting.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c18c9f2d6c614e168f82ef75dc0ed8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSettings.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSettings.cs new file mode 100644 index 000000000..388d36fba --- /dev/null +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSettings.cs @@ -0,0 +1,20 @@ +public class MfaSettings +{ + public MfaSetting? deviceShareFactor { get; set; } + public MfaSetting? backUpShareFactor { get; set; } + public MfaSetting? socialBackupFactor { get; set; } + public MfaSetting? passwordFactor { get; set; } + + // Constructors + public MfaSettings( + MfaSetting? deviceShareFactor, + MfaSetting? backUpShareFactor, + MfaSetting? socialBackupFactor, + MfaSetting? passwordFactor) + { + this.deviceShareFactor = deviceShareFactor; + this.backUpShareFactor = backUpShareFactor; + this.socialBackupFactor = socialBackupFactor; + this.passwordFactor = passwordFactor; + } +} \ No newline at end of file diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSettings.cs.meta b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSettings.cs.meta new file mode 100644 index 000000000..a65d58893 --- /dev/null +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/MfaSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 84c44fcb449df4b2db451e85439e068d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/SecurePlayerPrefs.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/SecurePlayerPrefs.cs index f69facb64..1d620416b 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/SecurePlayerPrefs.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/SecurePlayerPrefs.cs @@ -9,12 +9,12 @@ * This uses DES Encryption to encrypt your player prefs. * * @author Rawand Fatih (rawandnf@gmail.com) - * Copyright � 2014 Rawand Fatih + * Copyright � 2014 Rawand Fatih */ public class SecurePlayerPrefs { - /* + /* * The key is splited to three parts: * - The prefix, first part. * - Three randomly generated characters for each device. @@ -22,24 +22,24 @@ public class SecurePlayerPrefs * These constants are used in storing the random part for each device, * And for the prefs it uses the random number instead of PRIVATE_KEY_RAND. */ - private static readonly string PRIVATE_KEY_PREFIX = "abcd"; - private static readonly string PRIVATE_KEY_RAND = "efg"; - private static readonly string PRIVATE_KEY_SUFFIX = "h"; + private static readonly string PRIVATE_KEY_PREFIX = "abcd"; + private static readonly string PRIVATE_KEY_RAND = "efg"; + private static readonly string PRIVATE_KEY_SUFFIX = "h"; - // The private key of DES encryption. - private static string privateKey; + // The private key of DES encryption. + private static string privateKey; - // Is the secure prefs initialized. - private static bool isInit = false; + // Is the secure prefs initialized. + private static bool isInit = false; - // Your private key to store the randomly generated key for each device. - private static readonly string RAND_KEY = "abcdefgh"; + // Your private key to store the randomly generated key for each device. + private static readonly string RAND_KEY = "abcdefgh"; - // Should errors/exceptions be logged. - private static bool logErrorsEnabled = false; + // Should errors/exceptions be logged. + private static bool logErrorsEnabled = false; - /** + /** * Initializes the encryptor. If its the frist time, it will generate * a random 3 digit number and puts it between private key and its appendix. * If this was initialized on this device before, it will load it and create @@ -48,107 +48,107 @@ public class SecurePlayerPrefs * You can also copy players current preferences if your moving from Unity's * PlayerPrefs to this secure one. */ - public static void Init() - { - if (HasKey(RAND_KEY)) - { - privateKey = PRIVATE_KEY_PREFIX + PRIVATE_KEY_RAND + PRIVATE_KEY_SUFFIX; - privateKey = GetString(RAND_KEY); - privateKey = PRIVATE_KEY_PREFIX + privateKey + PRIVATE_KEY_SUFFIX; - } - else - { - int rand = UnityEngine.Random.Range(100, 1000); - privateKey = PRIVATE_KEY_PREFIX + PRIVATE_KEY_RAND + PRIVATE_KEY_SUFFIX; - SetInt(RAND_KEY, rand); - privateKey = PRIVATE_KEY_PREFIX + rand + PRIVATE_KEY_SUFFIX; - /* + public static void Init() + { + if (HasKey(RAND_KEY)) + { + privateKey = PRIVATE_KEY_PREFIX + PRIVATE_KEY_RAND + PRIVATE_KEY_SUFFIX; + privateKey = GetString(RAND_KEY); + privateKey = PRIVATE_KEY_PREFIX + privateKey + PRIVATE_KEY_SUFFIX; + } + else + { + int rand = UnityEngine.Random.Range(100, 1000); + privateKey = PRIVATE_KEY_PREFIX + PRIVATE_KEY_RAND + PRIVATE_KEY_SUFFIX; + SetInt(RAND_KEY, rand); + privateKey = PRIVATE_KEY_PREFIX + rand + PRIVATE_KEY_SUFFIX; + /* * Add copying PlayerPrefs to SecurePlayerPrefs code here. * See the example at GitHub. www.github.com/rawandnf/SecurePlayerPrefs */ - } - isInit = true; - } + } + isInit = true; + } - /** + /** * Is the decryptor initialized. */ - public static bool isInitialized() - { - return isInit; - } + public static bool isInitialized() + { + return isInit; + } - /** + /** * Converts unsecure player prefs to secure player prefs. * * Basically translates the prefs to secure ones. * @param keynames Is the list of keys with old and new name, [old name][new name][type]. * @param deleteOldKeys Should it delete the old keys. */ - private static void securePlayerPrefs(string[,] keynames, bool deleteOldKeys) - { - for (int i = 0; i < keynames.GetLength(0); i++) - { - if (keynames[i, 2].Equals("int")) - { - // Getting the integer and saving it encrypted. - int temp = PlayerPrefs.GetInt(keynames[i, 0]); - if (deleteOldKeys) - { - PlayerPrefs.DeleteKey(keynames[i, 0]); - } - SetInt(keynames[i, 1], temp); - } - else if (keynames[i, 2].Equals("float")) - { - // Getting the float and saving it encrypted. - float temp = PlayerPrefs.GetFloat(keynames[i, 0]); - if (deleteOldKeys) - { - PlayerPrefs.DeleteKey(keynames[i, 0]); - } - SetFloat(keynames[i, 1], temp); - } - else - { - // If not a float and int, then we take it as a string and save it encrypted. - string temp = PlayerPrefs.GetString(keynames[i, 0]); - if (deleteOldKeys) - { - PlayerPrefs.DeleteKey(keynames[i, 0]); - } - SetString(keynames[i, 1], temp); - } - } - Save(); - } - - - /** + private static void securePlayerPrefs(string[,] keynames, bool deleteOldKeys) + { + for (int i = 0; i < keynames.GetLength(0); i++) + { + if (keynames[i, 2].Equals("int")) + { + // Getting the integer and saving it encrypted. + int temp = PlayerPrefs.GetInt(keynames[i, 0]); + if (deleteOldKeys) + { + PlayerPrefs.DeleteKey(keynames[i, 0]); + } + SetInt(keynames[i, 1], temp); + } + else if (keynames[i, 2].Equals("float")) + { + // Getting the float and saving it encrypted. + float temp = PlayerPrefs.GetFloat(keynames[i, 0]); + if (deleteOldKeys) + { + PlayerPrefs.DeleteKey(keynames[i, 0]); + } + SetFloat(keynames[i, 1], temp); + } + else + { + // If not a float and int, then we take it as a string and save it encrypted. + string temp = PlayerPrefs.GetString(keynames[i, 0]); + if (deleteOldKeys) + { + PlayerPrefs.DeleteKey(keynames[i, 0]); + } + SetString(keynames[i, 1], temp); + } + } + Save(); + } + + + /** * Change the state of error log enabled. * * @param state The new state of error log enabled. */ - public static void setLogErrorsEnabled(bool state) - { - logErrorsEnabled = state; - } + public static void setLogErrorsEnabled(bool state) + { + logErrorsEnabled = state; + } - /** + /** * Saves a string in player preferences but securly encrypted. * @param key The preference id. * @param val The value of the preference, it will be encrypted. */ - public static void SetString(string key, string val) - { - PlayerPrefs.SetString(key, Encrypt(val)); - } + public static void SetString(string key, string val) + { + PlayerPrefs.SetString(key, Encrypt(val)); + } - /** + /** * Saves a float in the player prefs securely encrypted. * Note that everything is saved as strings, but can use methods provided * in this class to get the float, or just get your string decrypt and parse @@ -158,13 +158,13 @@ public static void SetString(string key, string val) * @param val The value of preference, it will be encrypted. * @see {@code #SetString(key: string, val: string)} */ - public static void SetFloat(string key, float val) - { - SetString(key, val + ""); - } + public static void SetFloat(string key, float val) + { + SetString(key, val + ""); + } - /** + /** * Saves a float in the player prefs securely encrypted. * Note that everything is saved as strings, but can use methods provided * in this class to get the int, or just get your string decrypt and parse @@ -174,216 +174,216 @@ public static void SetFloat(string key, float val) * @param val The value of preference, it will be encrypted. * @see {@code #SetString(key: string, val: string)} */ - public static void SetInt(string key, int val) - { - SetString(key, val + ""); - } + public static void SetInt(string key, int val) + { + SetString(key, val + ""); + } - /** + /** * Save a boolean in the player prefs. * * @param key The preference id. * @param val The value of preference, it will be encrypted. * @see {@code #SetString(key: string, val: bool)} */ - public static void SetBool(string key, bool val) - { - SetInt(key, ((val) ? 1 : 0)); - } + public static void SetBool(string key, bool val) + { + SetInt(key, ((val) ? 1 : 0)); + } - /** + /** * Get a securly encrypted text from the player preferences. * * @param key The id of the player preferences. * @param defaultValue The default to return. * @return The decrypted value or default in case of not found. */ - public static string GetString(String key, String defaultValue) - { - string s = PlayerPrefs.GetString(key, defaultValue); - if (s != defaultValue && s != "" && s != null) - { - try - { - return Decrypt(s); - } - catch (Exception ex) - { - if (logErrorsEnabled) - { - Debug.Log(ex.StackTrace); - } - } - } - return defaultValue; - } - - - /** + public static string GetString(String key, String defaultValue) + { + string s = PlayerPrefs.GetString(key, defaultValue); + if (s != defaultValue && s != "" && s != null) + { + try + { + return Decrypt(s); + } + catch (Exception ex) + { + if (logErrorsEnabled) + { + Debug.Log(ex.StackTrace); + } + } + } + return defaultValue; + } + + + /** * Get a securly encrypted text from the player preferences. * * @param key The id of the player preferences. * @return The decrypted value or default in case of not found. * @see {@ GetString(key : string, defaultValue : string) */ - public static string GetString(string key) - { - return GetString(key, ""); - } + public static string GetString(string key) + { + return GetString(key, ""); + } - /** + /** * Get a securly encrypted int from the player preferences. * * @param key The id of the player preferences. * @param defaultValue The default to return. * @return The decrypted value or default in case of not found */ - public static int GetInt(String key, int defaultValue) - { - string s = PlayerPrefs.GetString(key); - if (s != "" && s != null) - { - try - { - string d = Decrypt(s); - int i = int.Parse(d); - return i; - } - catch (Exception ex) - { - if (logErrorsEnabled) - { - Debug.Log(ex.StackTrace); - } - } - } - return defaultValue; - } - - - /** + public static int GetInt(String key, int defaultValue) + { + string s = PlayerPrefs.GetString(key); + if (s != "" && s != null) + { + try + { + string d = Decrypt(s); + int i = int.Parse(d); + return i; + } + catch (Exception ex) + { + if (logErrorsEnabled) + { + Debug.Log(ex.StackTrace); + } + } + } + return defaultValue; + } + + + /** * Get a securly encrypted int from the player preferences. * * @param key The id of the player preferences. * @return The decrypted value or default in case of not found. * @see {@ GetInt(key : string, defaultValue : int) */ - public static int GetInt(string key) - { - return GetInt(key, 0); - } + public static int GetInt(string key) + { + return GetInt(key, 0); + } - /** + /** * Get a securly encrypted float from the player preferences. * * @param key The id of the player preferences. * @param defaultValue The default to return. * @return The decrypted value or default in case of not found */ - public static float GetFloat(String key, float defaultValue) - { - string s = PlayerPrefs.GetString(key); - if (s != "" && s != null) - { - try - { - string d = Decrypt(s); - float f = float.Parse(d); - return f; - } - catch (Exception ex) - { - if (logErrorsEnabled) - { - Debug.Log(ex.StackTrace); - } - } - } - return defaultValue; - } - - - /** + public static float GetFloat(String key, float defaultValue) + { + string s = PlayerPrefs.GetString(key); + if (s != "" && s != null) + { + try + { + string d = Decrypt(s); + float f = float.Parse(d); + return f; + } + catch (Exception ex) + { + if (logErrorsEnabled) + { + Debug.Log(ex.StackTrace); + } + } + } + return defaultValue; + } + + + /** * Get a securly encrypted float from the player preferences. * * @param key The id of the player preferences. * @return The decrypted value or default in case of not found. * @see {@ GetFloat(key : string, defaultValue : float) */ - public static float GetFloat(string key) - { - return GetFloat(key, 0); - } + public static float GetFloat(string key) + { + return GetFloat(key, 0); + } - /** + /** * Get a securly encrypted bool from the player preferences. * * @param key The id of the player preferences. * @param defaultValue the default value to return. * @return The decrypted value or default in case of not found. */ - public static bool GetBool(string key, bool defaultValue) - { - int i = GetInt(key); - if (i == 1) - { - return true; - } - return defaultValue; - } - - - /** + public static bool GetBool(string key, bool defaultValue) + { + int i = GetInt(key); + if (i == 1) + { + return true; + } + return defaultValue; + } + + + /** * Get a securly encrypted bool from the player preferences. * * @param key The id of the player preferences. * @return The decrypted value or default in case of not found. * @see {@ GetBool(key : string, defaultValue : bool) */ - public static bool GetBool(string key) - { - return GetBool(key, false); - } + public static bool GetBool(string key) + { + return GetBool(key, false); + } - /** + /** * Removes key and its corresponding value from the preferences. * * @param key The id of the player preferences. */ - public static void DeleteKey(string key) - { - PlayerPrefs.DeleteKey(key); - } + public static void DeleteKey(string key) + { + PlayerPrefs.DeleteKey(key); + } - /** + /** * Removes all keys and values from the preferences. * Use with caution. */ - public static void DeleteAll() - { - PlayerPrefs.DeleteAll(); - } + public static void DeleteAll() + { + PlayerPrefs.DeleteAll(); + } - /** + /** * Returns true if key exists in the preferences. * * @param key The id of the preference. */ - public static bool HasKey(string key) - { - return PlayerPrefs.HasKey(key); - } + public static bool HasKey(string key) + { + return PlayerPrefs.HasKey(key); + } - /** + /** * Writes all modified preferences to disk. * * By default Unity writes preferences to disk on Application Quit. @@ -392,57 +392,57 @@ public static bool HasKey(string key) * in your game. This function will write to disk potentially causing * a small hiccup, therefore it is not recommended to call during actual gameplay. */ - public static void Save() - { - PlayerPrefs.Save(); - } + public static void Save() + { + PlayerPrefs.Save(); + } - /** + /** * Decrypts a cipher with DES. * * @param encryptedString The cipher to decrypt. */ - private static string Decrypt(string encryptedString) - { - DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider(); - desProvider.Mode = CipherMode.ECB; - desProvider.Padding = PaddingMode.PKCS7; - desProvider.Key = Encoding.ASCII.GetBytes(privateKey); - using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(encryptedString))) - { - using (CryptoStream cs = new CryptoStream(stream, desProvider.CreateDecryptor(), CryptoStreamMode.Read)) - { - using (StreamReader sr = new StreamReader(cs, Encoding.ASCII)) - { - return sr.ReadToEnd(); - } - } - } - } - - - /** + private static string Decrypt(string encryptedString) + { + DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider(); + desProvider.Mode = CipherMode.ECB; + desProvider.Padding = PaddingMode.PKCS7; + desProvider.Key = Encoding.ASCII.GetBytes(privateKey); + using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(encryptedString))) + { + using (CryptoStream cs = new CryptoStream(stream, desProvider.CreateDecryptor(), CryptoStreamMode.Read)) + { + using (StreamReader sr = new StreamReader(cs, Encoding.ASCII)) + { + return sr.ReadToEnd(); + } + } + } + } + + + /** * Encrypt a plain text with DES. * * @param plainText The text to encrypt. */ - private static string Encrypt(string plainText) - { - DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider(); - desProvider.Mode = CipherMode.ECB; - desProvider.Padding = PaddingMode.PKCS7; - desProvider.Key = Encoding.ASCII.GetBytes(privateKey); - using (MemoryStream stream = new MemoryStream()) - { - using (CryptoStream cs = new CryptoStream(stream, desProvider.CreateEncryptor(), CryptoStreamMode.Write)) - { - byte[] data = Encoding.Default.GetBytes(plainText); - cs.Write(data, 0, data.Length); - cs.FlushFinalBlock(); // <-- Add this - return Convert.ToBase64String(stream.ToArray()); - } - } - } + private static string Encrypt(string plainText) + { + DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider(); + desProvider.Mode = CipherMode.ECB; + desProvider.Padding = PaddingMode.PKCS7; + desProvider.Key = Encoding.ASCII.GetBytes(privateKey); + using (MemoryStream stream = new MemoryStream()) + { + using (CryptoStream cs = new CryptoStream(stream, desProvider.CreateEncryptor(), CryptoStreamMode.Write)) + { + byte[] data = Encoding.Default.GetBytes(plainText); + cs.Write(data, 0, data.Length); + cs.FlushFinalBlock(); // <-- Add this + return Convert.ToBase64String(stream.ToArray()); + } + } + } } \ No newline at end of file diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ShareMetadata.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ShareMetadata.cs index d29845ae8..3cbbef288 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ShareMetadata.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/ShareMetadata.cs @@ -1,7 +1,7 @@ public class ShareMetadata { - public string iv { get; set; } + public string iv { get; set; } public string ephemPublicKey { get; set; } public string ciphertext { get; set; } public string mac { get; set; } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/UserInfo.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/UserInfo.cs index c2eb6fed5..9de1c61c0 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/UserInfo.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/UserInfo.cs @@ -11,4 +11,5 @@ public string idToken { get; set; } public string oAuthIdToken { get; set; } public string oAuthAccessToken { get; set; } + public bool isMfaEnabled { get; set; } } diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/Web3AuthOptions.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/Web3AuthOptions.cs index e00754e12..2ed4dfc20 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/Web3AuthOptions.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/Web3AuthOptions.cs @@ -1,25 +1,29 @@ using System; using System.Collections.Generic; +#nullable enable -public class Web3AuthOptions -{ +public class Web3AuthOptions { public string clientId { get; set; } public Web3Auth.Network network { get; set; } + + public Web3Auth.BuildEnv buildEnv { get; set; } = Web3Auth.BuildEnv.PRODUCTION; public Uri redirectUrl { get; set; } - public string sdkUrl - { - get - { - if (network == Web3Auth.Network.TESTNET) - return "https://dev-sdk.openlogin.com"; - else - return "https://sdk.openlogin.com"; + public string sdkUrl { + get { + if (buildEnv == Web3Auth.BuildEnv.STAGING) + return "https://staging-auth.web3auth.io/{openLoginVersion}"; + else if (buildEnv == Web3Auth.BuildEnv.TESTING) + return "https://develop-auth.web3auth.io"; + else + return "https://auth.web3auth.io/{openLoginVersion}"; } set { } } + public const string openLoginVersion = "v5"; - public WhiteLabelData whiteLabel { get; set; } - public Dictionary loginConfig { get; set; } + public WhiteLabelData? whiteLabel { get; set; } + public Dictionary? loginConfig { get; set; } public bool? useCoreKitKey { get; set; } = false; public Web3Auth.ChainNamespace? chainNamespace { get; set; } = Web3Auth.ChainNamespace.EIP155; + public MfaSettings? mfaSettings { get; set; } = null; } \ No newline at end of file diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/WhiteLabelData.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/WhiteLabelData.cs index 4164a0f1c..8d11ef18d 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/WhiteLabelData.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Types/WhiteLabelData.cs @@ -1,11 +1,12 @@ using System.Collections.Generic; - -public class WhiteLabelData -{ - public string name { get; set; } - public string logoLight { get; set; } - public string logoDark { get; set; } - public string defaultLanguage { get; set; } = "en"; - public bool dark { get; set; } = false; - public Dictionary theme { get; set; } +#nullable enable +public class WhiteLabelData { + public string? appName { get; set; } + public string? logoLight { get; set; } + public string? logoDark { get; set; } + public Web3Auth.Language? defaultLanguage { get; set; } = Web3Auth.Language.en; + public Web3Auth.ThemeModes? mode { get; set; } = Web3Auth.ThemeModes.light; + public Dictionary? theme { get; set; } + public string? appUrl { get; set; } + public bool? useLogoLoader { get; set; } = false; } \ No newline at end of file diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3Auth.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3Auth.cs index 51752928e..faf1b6c64 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3Auth.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3Auth.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using System; using System.Collections.Generic; using System.Text; @@ -8,15 +9,13 @@ using System.Collections; using Org.BouncyCastle.Math; using Newtonsoft.Json.Linq; -#if UNITY_WEBGL && !UNITY_EDITOR -using System.Runtime.InteropServices; -#endif +using System.Threading.Tasks; public class Web3Auth : MonoBehaviour { public enum Network { - MAINNET, TESTNET, CYAN, AQUA + MAINNET, TESTNET, CYAN, AQUA, SAPPHIRE_DEVNET, SAPPHIRE_MAINNET } public enum ChainNamespace @@ -24,6 +23,21 @@ public enum ChainNamespace EIP155, SOLANA } + public enum BuildEnv + { + PRODUCTION, STAGING, TESTING + } + + public enum ThemeModes + { + light, dark, auto + } + + public enum Language + { + en, de, ja, ko, zh, es, fr, pt, nl + } + private Web3AuthOptions web3AuthOptions; private Dictionary initParams; @@ -32,8 +46,6 @@ public enum ChainNamespace public event Action onLogin; public event Action onLogout; - private bool initializeOnStart; - [SerializeField] private string clientId; @@ -45,28 +57,7 @@ public enum ChainNamespace private static readonly Queue _executionQueue = new Queue(); -#if UNITY_WEBGL && !UNITY_EDITOR - [DllImport("__Internal")] - private static extern string GetAddressBarURL(); -#endif - public void Awake() - { - if (!initializeOnStart) - return; - - Initialize(); - } - - private void OnDestroy() - { - // Better be safe than sorry and remove the event listener when the object is destroyed so we don't have - // Memory leaks. - Application.deepLinkActivated -= onDeepLinkActivated; - } - - - public void Initialize() { this.initParams = new Dictionary(); @@ -77,46 +68,34 @@ public void Initialize() this.initParams["redirectUrl"] = redirectUri; Application.deepLinkActivated += onDeepLinkActivated; - var absoluteURL = GetAbsoluteURL(); - if (!string.IsNullOrEmpty(absoluteURL)) - { - onDeepLinkActivated(absoluteURL); - } + if (!string.IsNullOrEmpty(Application.absoluteURL)) + onDeepLinkActivated(Application.absoluteURL); + #if UNITY_EDITOR Web3AuthSDK.Editor.Web3AuthDebug.onURLRecieved += (Uri url) => { this.setResultUrl(url); }; - //#elif UNITY_WEBGL - // var code = Utils.GetAuthCode(); - // Debug.Log("code is " + code); - // if (Utils.GetAuthCode() != "") - // { - // Debug.Log("I am here"); - // this.setResultUrl(new Uri($"http://localhost#{code}")); - // } -#endif -#if UNITY_WEBGL - authorizeSession(); -#endif - } - - private string GetAbsoluteURL() - { - //Because we can't change Unitys Application.absoluteURL we need to use a workaround for WebGL. - //There is a ReadAddressBar.jslib file in the plugins folder that is kinda like a bridge - //Between Unity's code and Javascript, there I retrieve the actual addressBar URL, which is used later. -#if UNITY_WEBGL && !UNITY_EDITOR - return GetAddressBarURL(); -#else - return Application.absoluteURL; +//#elif UNITY_WEBGL +// var code = Utils.GetAuthCode(); +// Debug.Log("code is " + code); +// if (Utils.GetAuthCode() != "") +// { +// Debug.Log("I am here"); +// this.setResultUrl(new Uri($"http://localhost#{code}")); +// } #endif + authorizeSession(""); } - public void setOptions(Web3AuthOptions web3AuthOptions) { + JsonSerializerSettings settings = new JsonSerializerSettings + { + Converters = new List { new StringEnumConverter() }, + Formatting = Formatting.Indented + }; this.web3AuthOptions = web3AuthOptions; @@ -124,22 +103,27 @@ public void setOptions(Web3AuthOptions web3AuthOptions) this.initParams["redirectUrl"] = this.web3AuthOptions.redirectUrl; if (this.web3AuthOptions.whiteLabel != null) - this.initParams["whiteLabel"] = JsonConvert.SerializeObject(this.web3AuthOptions.whiteLabel); + this.initParams["whiteLabel"] = JsonConvert.SerializeObject(this.web3AuthOptions.whiteLabel, settings); if (this.web3AuthOptions.loginConfig != null) - this.initParams["loginConfig"] = JsonConvert.SerializeObject(this.web3AuthOptions.loginConfig); + this.initParams["loginConfig"] = JsonConvert.SerializeObject(this.web3AuthOptions.loginConfig, settings); if (this.web3AuthOptions.clientId != null) this.initParams["clientId"] = this.web3AuthOptions.clientId; - this.initParams["network"] = this.web3AuthOptions.network.ToString().ToLower(); + if (this.web3AuthOptions.buildEnv != null) + this.initParams["buildEnv"] = this.web3AuthOptions.buildEnv.ToString().ToLower(); + this.initParams["network"] = this.web3AuthOptions.network.ToString().ToLower(); if (this.web3AuthOptions.useCoreKitKey.HasValue) this.initParams["useCoreKitKey"] = this.web3AuthOptions.useCoreKitKey.Value; if (this.web3AuthOptions.chainNamespace != null) this.initParams["chainNamespace"] = this.web3AuthOptions.chainNamespace; + + if (this.web3AuthOptions.mfaSettings != null) + this.initParams["mfaSettings"] = JsonConvert.SerializeObject(this.web3AuthOptions.mfaSettings, settings); } private void onDeepLinkActivated(string url) @@ -257,34 +241,55 @@ private void IncomingHttpRequest(IAsyncResult result) } #endif - private void request(string path, LoginParams loginParams = null, Dictionary extraParams = null) + private async void request(string path, LoginParams loginParams = null, Dictionary extraParams = null) { #if UNITY_STANDALONE || UNITY_EDITOR this.initParams["redirectUrl"] = StartLocalWebserver(); #elif UNITY_WEBGL this.initParams["redirectUrl"] = Utils.GetCurrentURL(); #endif + + this.initParams["sessionTime"] = loginParams.sessionTime; + loginParams.redirectUrl = loginParams.redirectUrl ?? new Uri(this.initParams["redirectUrl"].ToString()); Dictionary paramMap = new Dictionary(); - paramMap["init"] = this.initParams; + paramMap["options"] = this.initParams; paramMap["params"] = loginParams == null ? (object)new Dictionary() : (object)loginParams; + paramMap["actionType"] = "login"; if (extraParams != null && extraParams.Count > 0) foreach (KeyValuePair item in extraParams) { (paramMap["params"] as Dictionary)[item.Key] = item.Value; } + //Debug.Log("paramMap: =>" + JsonConvert.SerializeObject(paramMap)); + string loginId = await createSession(JsonConvert.SerializeObject(paramMap, Formatting.None, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }), 600); - string hash = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(paramMap, Newtonsoft.Json.Formatting.None, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }))); + if (!string.IsNullOrEmpty(loginId)) + { + var loginIdObject = new Dictionary + { + { "loginId", loginId } + }; + string hash = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(loginIdObject, Formatting.None, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }))); - UriBuilder uriBuilder = new UriBuilder(this.web3AuthOptions.sdkUrl); - uriBuilder.Path = path; - uriBuilder.Fragment = hash; + UriBuilder uriBuilder = new UriBuilder(this.web3AuthOptions.sdkUrl); + uriBuilder.Path = path; + uriBuilder.Fragment = "b64Params=" + hash; - Utils.LaunchUrl(uriBuilder.ToString(), this.initParams["redirectUrl"].ToString(), gameObject.name); + Utils.LaunchUrl(uriBuilder.ToString(), this.initParams["redirectUrl"].ToString(), gameObject.name); + } + else + { + throw new Exception("Some went wrong. Please try again later."); + } } public void setResultUrl(Uri uri) @@ -298,30 +303,19 @@ public void setResultUrl(Uri uri) throw new UserCancelledException(); #endif hash = hash.Remove(0, 1); - Dictionary queryParameters = Utils.ParseQuery(uri.Query); if (queryParameters.Keys.Contains("error")) throw new UnKnownException(queryParameters["error"]); - this.web3AuthResponse = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(Utils.DecodeBase64(hash))); - if (!string.IsNullOrEmpty(this.web3AuthResponse.error)) - throw new UnKnownException(web3AuthResponse.error); - - if (string.IsNullOrEmpty(this.web3AuthResponse.privKey) || string.IsNullOrEmpty(this.web3AuthResponse.privKey.Trim('0'))) - this.Enqueue(() => this.onLogout?.Invoke()); - else - this.Enqueue(() => this.onLogin?.Invoke(this.web3AuthResponse)); + string sessionId = hash.Split('&')[0].Split('=')[1]; - if (!string.IsNullOrEmpty(this.web3AuthResponse.sessionId)) - this.Enqueue(() => KeyStoreManagerUtils.savePreferenceData(KeyStoreManagerUtils.SESSION_ID, this.web3AuthResponse.sessionId)); + //save new sessionId + this.Enqueue(() => KeyStoreManagerUtils.savePreferenceData(KeyStoreManagerUtils.SESSION_ID, sessionId)); - if (!string.IsNullOrEmpty(web3AuthResponse.userInfo?.dappShare)) - { - KeyStoreManagerUtils.savePreferenceData( - web3AuthResponse.userInfo?.verifier, web3AuthResponse.userInfo?.dappShare - ); - } + //call authorize session API + // Debug.Log("publickey after successful redirection from web. =>" + sessionId); + this.Enqueue(() => authorizeSession(sessionId)); #if !UNITY_EDITOR && UNITY_WEBGL if (this.web3AuthResponse != null) @@ -344,7 +338,7 @@ public void login(LoginParams loginParams) } } - request("login", loginParams); + request("start", loginParams); } public void logout(Dictionary extraParams) @@ -364,9 +358,20 @@ public void logout(Uri redirectUrl = null, string appState = null) logout(extraParams); } - private void authorizeSession() + private void authorizeSession(string newSessionId) { - string sessionId = KeyStoreManagerUtils.getPreferencesData(KeyStoreManagerUtils.SESSION_ID); + string sessionId = ""; + if (string.IsNullOrEmpty(newSessionId)) + { + sessionId = KeyStoreManagerUtils.getPreferencesData(KeyStoreManagerUtils.SESSION_ID); + // Debug.Log("sessionId during authorizeSession in if part =>" + sessionId); + } + else + { + sessionId = newSessionId; + // Debug.Log("sessionId during authorizeSession in else part =>" + sessionId); + } + if (!string.IsNullOrEmpty(sessionId)) { var pubKey = KeyStoreManagerUtils.getPubKey(sessionId); @@ -383,15 +388,10 @@ private void authorizeSession() ); var encryptedShareBytes = AES256CBC.toByteArray(new BigInteger(shareMetadata.ciphertext, 16)); - var share = aes256cbc.decrypt(encryptedShareBytes); - var tempJson = JsonConvert.DeserializeObject(share); - if (!tempJson.ContainsKey("userInfo")) - tempJson.Add("userInfo", null); - tempJson["userInfo"] = tempJson["store"]; - tempJson.Remove("store"); + var share = aes256cbc.decrypt(encryptedShareBytes, shareMetadata.mac); + var tempJson = JsonConvert.DeserializeObject(System.Text.Encoding.UTF8.GetString(share)); this.web3AuthResponse = JsonConvert.DeserializeObject(tempJson.ToString()); - if (this.web3AuthResponse != null) { if (this.web3AuthResponse.error != null) @@ -399,6 +399,18 @@ private void authorizeSession() throw new UnKnownException(this.web3AuthResponse.error ?? "Something went wrong"); } + if (!string.IsNullOrEmpty(this.web3AuthResponse.sessionId)) + { + KeyStoreManagerUtils.savePreferenceData(KeyStoreManagerUtils.SESSION_ID, this.web3AuthResponse.sessionId); + } + + if (!string.IsNullOrEmpty(web3AuthResponse.userInfo?.dappShare)) + { + KeyStoreManagerUtils.savePreferenceData( + web3AuthResponse.userInfo?.verifier, web3AuthResponse.userInfo?.dappShare + ); + } + if (string.IsNullOrEmpty(this.web3AuthResponse.privKey) || string.IsNullOrEmpty(this.web3AuthResponse.privKey.Trim('0'))) this.Enqueue(() => this.onLogout?.Invoke()); else @@ -433,7 +445,7 @@ private void sessionTimeOutAPI() { iv = shareMetadata.iv, ephemPublicKey = shareMetadata.ephemPublicKey, - ciphertext = encryptedData, + ciphertext = KeyStoreManagerUtils.convertByteToHexadecimal(encryptedData), mac = shareMetadata.mac }; var jsonData = JsonConvert.SerializeObject(encryptedMetadata); @@ -455,7 +467,8 @@ private void sessionTimeOutAPI() try { KeyStoreManagerUtils.deletePreferencesData(KeyStoreManagerUtils.SESSION_ID); - KeyStoreManagerUtils.deletePreferencesData(web3AuthOptions.loginConfig?.Values.First()?.verifier); + if (web3AuthOptions.loginConfig != null) + KeyStoreManagerUtils.deletePreferencesData(web3AuthOptions.loginConfig?.Values.First()?.verifier); this.Enqueue(() => this.onLogout?.Invoke()); } @@ -471,6 +484,64 @@ private void sessionTimeOutAPI() } } + private async Task createSession(string data, long sessionTime) + { + TaskCompletionSource createSessionResponse = new TaskCompletionSource(); + var newSessionKey = KeyStoreManagerUtils.generateRandomSessionKey(); + // Debug.Log("newSessionKey =>" + newSessionKey); + var ephemKey = KeyStoreManagerUtils.getPubKey(newSessionKey); + var ivKey = KeyStoreManagerUtils.generateRandomBytes(); + + var aes256cbc = new AES256CBC( + newSessionKey, + ephemKey, + KeyStoreManagerUtils.convertByteToHexadecimal(ivKey) + ); + var encryptedData = aes256cbc.encrypt(System.Text.Encoding.UTF8.GetBytes(data)); + var mac = aes256cbc.getMac(encryptedData); + var encryptedMetadata = new ShareMetadata() + { + iv = KeyStoreManagerUtils.convertByteToHexadecimal(ivKey), + ephemPublicKey = ephemKey, + ciphertext = KeyStoreManagerUtils.convertByteToHexadecimal(encryptedData), + mac = KeyStoreManagerUtils.convertByteToHexadecimal(mac) + }; + var jsonData = JsonConvert.SerializeObject(encryptedMetadata); + StartCoroutine(Web3AuthApi.getInstance().createSession( + new LogoutApiRequest() + { + key = KeyStoreManagerUtils.getPubKey(newSessionKey), + data = jsonData, + signature = KeyStoreManagerUtils.getECDSASignature( + newSessionKey, + jsonData + ), + timeout = Math.Min(sessionTime, 7 * 86400) + }, result => + { + if (result != null) + { + try + { + // Debug.Log("newSessionKey before saving into keystore =>" + newSessionKey); + this.Enqueue(() => KeyStoreManagerUtils.savePreferenceData(KeyStoreManagerUtils.SESSION_ID, newSessionKey)); + createSessionResponse.SetResult(newSessionKey); + } + catch (Exception ex) + { + createSessionResponse.SetException(new Exception("Something went wrong. Please try again later.")); + Debug.LogError(ex.Message); + } + } + else + { + createSessionResponse.SetException(new Exception("Something went wrong. Please try again later.")); + } + } + )); + return await createSessionResponse.Task; + } + public string getPrivKey() { if (web3AuthResponse == null) diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3AuthExceptions.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3AuthExceptions.cs index 9aef3b252..0750fc68d 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3AuthExceptions.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Plugins/Web3AuthSDK/Web3AuthExceptions.cs @@ -2,7 +2,7 @@ public class UserCancelledException : Exception { - public UserCancelledException() : base("User cancelled.") { } + public UserCancelledException(): base("User cancelled.") { } } public class UnKnownException : Exception diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Web3AuthWallet.cs b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Web3AuthWallet.cs index ee6b3fb3e..624e64fb8 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Web3AuthWallet.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Runtime/Web3AuthWallet.cs @@ -122,7 +122,7 @@ private TWeb3Auth CreateCoreInstance() Object.DontDestroyOnLoad(gameObject); var instance = gameObject.GetComponent(); - instance.Initialize(); + instance.Awake(); instance.setOptions(config.Web3AuthOptions); return instance; diff --git a/Packages/io.chainsafe.web3-unity.web3auth/Samples~/Web3.Unity Web3Auth/Scripts/Web3AuthLogin.cs b/Packages/io.chainsafe.web3-unity.web3auth/Samples~/Web3.Unity Web3Auth/Scripts/Web3AuthLogin.cs index 93b677735..1b7d278ab 100644 --- a/Packages/io.chainsafe.web3-unity.web3auth/Samples~/Web3.Unity Web3Auth/Scripts/Web3AuthLogin.cs +++ b/Packages/io.chainsafe.web3-unity.web3auth/Samples~/Web3.Unity Web3Auth/Scripts/Web3AuthLogin.cs @@ -87,9 +87,9 @@ protected override Web3Builder ConfigureWeb3Services(Web3Builder web3Builder) network = network, whiteLabel = new() { - dark = true, - defaultLanguage = "en", - name = "ChainSafe Gaming SDK", + mode = Web3Auth.ThemeModes.dark, + defaultLanguage = Web3Auth.Language.en, + appName = "ChainSafe Gaming SDK", } } }; diff --git a/src/UnitySampleProject/Assets/PlayerData.json b/src/UnitySampleProject/Assets/PlayerData.json new file mode 100644 index 000000000..3aa8c0f3f --- /dev/null +++ b/src/UnitySampleProject/Assets/PlayerData.json @@ -0,0 +1 @@ +{"WalletConnectConfig":null} diff --git a/src/UnitySampleProject/Assets/PlayerData.json.meta b/src/UnitySampleProject/Assets/PlayerData.json.meta new file mode 100644 index 000000000..7e6a8d520 --- /dev/null +++ b/src/UnitySampleProject/Assets/PlayerData.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f3c322c946d55d34eaadaf3a50312c5c +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/UnitySampleProject/Assets/Plugins.meta b/src/UnitySampleProject/Assets/Plugins.meta new file mode 100644 index 000000000..a64f6fd98 --- /dev/null +++ b/src/UnitySampleProject/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9265622591a5741fca8ccae4087d191a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/UnitySampleProject/Assets/Samples/web3.unity SDK Web3Auth/2.5.1/Web3.Unity Web3Auth Samples/Scripts/Web3AuthLogin.cs b/src/UnitySampleProject/Assets/Samples/web3.unity SDK Web3Auth/2.5.1/Web3.Unity Web3Auth Samples/Scripts/Web3AuthLogin.cs index 93b677735..1b7d278ab 100644 --- a/src/UnitySampleProject/Assets/Samples/web3.unity SDK Web3Auth/2.5.1/Web3.Unity Web3Auth Samples/Scripts/Web3AuthLogin.cs +++ b/src/UnitySampleProject/Assets/Samples/web3.unity SDK Web3Auth/2.5.1/Web3.Unity Web3Auth Samples/Scripts/Web3AuthLogin.cs @@ -87,9 +87,9 @@ protected override Web3Builder ConfigureWeb3Services(Web3Builder web3Builder) network = network, whiteLabel = new() { - dark = true, - defaultLanguage = "en", - name = "ChainSafe Gaming SDK", + mode = Web3Auth.ThemeModes.dark, + defaultLanguage = Web3Auth.Language.en, + appName = "ChainSafe Gaming SDK", } } };