diff --git a/Assets/Stash/Scripts/Core/StashConstants.cs b/Assets/Stash/Scripts/Core/StashConstants.cs index e4bd66f..9af78c3 100644 --- a/Assets/Stash/Scripts/Core/StashConstants.cs +++ b/Assets/Stash/Scripts/Core/StashConstants.cs @@ -8,9 +8,13 @@ public class StashConstants //Account Linking public const string LinkAccount = "/sdk/link_code/link"; - public const string CustomLogin = "/sdk/custom_login/approve_with_jwt"; public const string LinkAppleGameCenter = "/sdk/link_code/link_apple_game_center"; public const string LinkGooglePlayGames = "/sdk/link_code/link_google_play"; + //Custom Login + public const string CustomLogin = "/sdk/custom_login/approve_with_jwt"; + public const string LoginAppleGameCenter = "/sdk/custom_login/approve_apple_game_center"; + public const string LoginGooglePlayGames = "/sdk/custom_login/google_play"; + } } diff --git a/Assets/Stash/Scripts/Core/StashCustomLogin.cs b/Assets/Stash/Scripts/Core/StashCustomLogin.cs new file mode 100644 index 0000000..8fa2b7e --- /dev/null +++ b/Assets/Stash/Scripts/Core/StashCustomLogin.cs @@ -0,0 +1,190 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using UnityEngine; +using Stash.Core.Exceptions; +using Stash.Models; +using Stash.Scripts.Core; + +namespace Stash.Core +{ + /// + /// Sign in to a Stash web shop using custom auth provider. + /// For linking to Stash account, use StashLink. + /// + +public static class StashCustomLogin +{ + /// + /// Log in to stash account created using 3rd party authentication provider. + /// For use with bespoke login provider. Not intended for general account linking. + /// + /// Stash code challenge from the log in deeplink. + /// Player identification, that will be used to identify purchases. + /// Valid identification token (OICD) of the player. + /// URL to the player's profile image/avatar to be displayed during login and on web shop. + /// Returns a confirmation response, or throws StashAPIRequestError if fails. + public static async Task CustomLogin(string code, string playerId, string idToken, string profileImageUrl, StashEnvironment environment = StashEnvironment.Test) + { + // Create the authorization header with the access token + RequestHeader authorizationHeader = new() + { + Key = "Authorization", + Value = "Bearer " + idToken + }; + + // Create the request body with the challenge and internal user id + var requestBody = new CustomLoginBody() + { + code = code, + user = new CustomLoginBody.User + { + id = playerId, + profile_image_url = profileImageUrl + } + }; + + // Set the URL for the link account endpoint + string requestUrl = environment.GetRootUrl() + StashConstants.CustomLogin; + // Make a POST request to link the access token + Response result = await RestClient.Post(requestUrl, JsonUtility.ToJson(requestBody), new List { authorizationHeader }); + + // Check the response status code + if (result.StatusCode == 200) + { + try + { + // Parse the response data into a LinkResponse object + LinkResponse resultResponse = JsonUtility.FromJson(result.Data); + return resultResponse; + } + catch + { + // Throw an error if there is an issue parsing the response data + throw new StashParseError(result.Data); + } + } + else + { + // Throw an error if the API request was not successful + throw new StashRequestError(result.StatusCode, result.Data); + } + } + + /// + /// Logs in to stash web shop via Apple Game Center account. + /// Requires a valid response (signature, salt, timestamp, publicKeyUrl) received from GameKit "fetchItems" no older than 1 hour. + /// + /// Stash code challenge from the deeplink. + /// Player identification, that will be used to identify purchases. + /// The bundle ID of the app (CFBundleIdentifier) + /// GameKit identifier for a player of all the games that you distribute using your Apple developer account. + /// The verification signature data that GameKit generates. (Base64 Encoded) + /// A random string that GameKit uses to compute the hash and randomize it. (Base64 Encoded) + /// The URL for the public encryption key. + /// The signature’s creation date and time. + /// Stash API environment (Defaults to Test). + /// A LinkResponse object. + public static async Task LinkAppleGameCenter(string code, string playerId, string bundleId, string teamPlayerID, string signature, + string salt, string publicKeyUrl, string timestamp, StashEnvironment environment = StashEnvironment.Test) + { + // Create the request body with the challenge and internal user id + var requestBody = new LoginGameCenterBody() + { + code = code, + verification = new LoginGameCenterBody.Verification() + { + player = new LoginGameCenterBody.Player() + { + bundleId = bundleId, + teamPlayerId = teamPlayerID + }, + response = new LoginGameCenterBody.Response() + { + signature = signature, + salt = salt, + publicKeyUrl = publicKeyUrl, + timestamp = timestamp + } + }, + user = new LoginGameCenterBody.User() + { + id = playerId + } + }; + + // Set the URL for the link account endpoint + string requestUrl = environment.GetRootUrl() + StashConstants.LoginAppleGameCenter; + // Make a POST request to link the access token + Response result = await RestClient.Post(requestUrl, JsonUtility.ToJson(requestBody)); + + // Check the response status code + if (result.StatusCode == 200) + { + try + { + LinkResponse resultResponse = JsonUtility.FromJson(result.Data); + return resultResponse; + } + catch + { + // Throw an error if there is an issue parsing the response data + throw new StashParseError(result.Data); + } + } + else + { + // Throw an error if the API request was not successful + throw new StashRequestError(result.StatusCode, result.Data); + } + } + + + /// + /// Logs in to stash web shop via Google Play Games account. + /// Requires valid authorization code generated using "RequestServerSideAccess" from GooglePlayGames no older than 1 hour. + /// + /// Stash code challenge from the deeplink. + /// Player identification, that will be used to identify purchases. + /// The authorization code generated using RequestServerSideAccess + /// A LinkResponse object. + public static async Task LinkGooglePlayGames(string code, string playerId, string authCode, StashEnvironment environment = StashEnvironment.Test) + { + // Create the request body with the challenge and internal user id + var requestBody = new LoginGooglePlayGamesBody() + { + code = code, + authCode = authCode, + user = new LoginGooglePlayGamesBody.User() + { + id = playerId + } + }; + + // Set the URL for the link account endpoint + string requestUrl = environment.GetRootUrl() + StashConstants.LoginGooglePlayGames; + // Make a POST request to link the access token + Response result = await RestClient.Post(requestUrl, JsonUtility.ToJson(requestBody)); + + // Check the response status code + if (result.StatusCode == 200) + { + try + { + Debug.Log("[RESPONSE RAW] " + result.Data); + LinkResponse resultResponse = JsonUtility.FromJson(result.Data); + return resultResponse; + } + catch + { + // Throw an error if there is an issue parsing the response data + throw new StashParseError(result.Data); + } + } + else + { + // Throw an error if the API request was not successful + throw new StashRequestError(result.StatusCode, result.Data); + } + } +} +} \ No newline at end of file diff --git a/Assets/Stash/Scripts/Core/StashCustomLogin.cs.meta b/Assets/Stash/Scripts/Core/StashCustomLogin.cs.meta new file mode 100644 index 0000000..0c3872e --- /dev/null +++ b/Assets/Stash/Scripts/Core/StashCustomLogin.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 93a7fe6cf7674c3fb7dc99198c84aa98 +timeCreated: 1720383631 \ No newline at end of file diff --git a/Assets/Stash/Scripts/Core/StashAuth.cs b/Assets/Stash/Scripts/Core/StashLink.cs similarity index 75% rename from Assets/Stash/Scripts/Core/StashAuth.cs rename to Assets/Stash/Scripts/Core/StashLink.cs index 910cacc..534d20e 100644 --- a/Assets/Stash/Scripts/Core/StashAuth.cs +++ b/Assets/Stash/Scripts/Core/StashLink.cs @@ -8,10 +8,11 @@ namespace Stash.Core { /// - /// Linking the player's account to Stash web shop or using 3rd party authentication provider. + /// Linking the player's account to Stash Account. + /// For a custom sing in, use StashCustomLogin. /// -public static class StashAuth +public static class StashLink { /// /// Links the player's account to Stash account for Apple Account & Google Account. @@ -186,60 +187,5 @@ public static async Task LinkGooglePlayGames(string challenge, str } } - /// - /// Log in to stash account created using 3rd party authentication provider. - /// For use with bespoke login provider. Not intended for general account linking. - /// - /// Stash code challenge from the log in deeplink. - /// Player identification, that will be used to identify purchases. - /// Valid identification token (OICD) of the player. - /// URL to the player's profile image/avatar to be displayed during login and on web shop. - /// Returns a confirmation response, or throws StashAPIRequestError if fails. - public static async Task CustomLogin(string code, string playerId, string idToken, string profileImageUrl, StashEnvironment environment = StashEnvironment.Test) - { - // Create the authorization header with the access token - RequestHeader authorizationHeader = new() - { - Key = "Authorization", - Value = "Bearer " + idToken - }; - - // Create the request body with the challenge and internal user id - var requestBody = new CustomLoginBody() - { - code = code, - user = new CustomLoginBody.User - { - id = playerId, - profile_image_url = profileImageUrl - } - }; - - // Set the URL for the link account endpoint - string requestUrl = environment.GetRootUrl() + StashConstants.CustomLogin; - // Make a POST request to link the access token - Response result = await RestClient.Post(requestUrl, JsonUtility.ToJson(requestBody), new List { authorizationHeader }); - - // Check the response status code - if (result.StatusCode == 200) - { - try - { - // Parse the response data into a LinkResponse object - LinkResponse resultResponse = JsonUtility.FromJson(result.Data); - return resultResponse; - } - catch - { - // Throw an error if there is an issue parsing the response data - throw new StashParseError(result.Data); - } - } - else - { - // Throw an error if the API request was not successful - throw new StashRequestError(result.StatusCode, result.Data); - } - } } } \ No newline at end of file diff --git a/Assets/Stash/Scripts/Core/StashAuth.cs.meta b/Assets/Stash/Scripts/Core/StashLink.cs.meta similarity index 100% rename from Assets/Stash/Scripts/Core/StashAuth.cs.meta rename to Assets/Stash/Scripts/Core/StashLink.cs.meta diff --git a/Assets/Stash/Scripts/Models/LoginGameCenterBody.cs b/Assets/Stash/Scripts/Models/LoginGameCenterBody.cs new file mode 100644 index 0000000..90e274f --- /dev/null +++ b/Assets/Stash/Scripts/Models/LoginGameCenterBody.cs @@ -0,0 +1,41 @@ +using System; + +namespace Stash.Models +{ + [Serializable] + public class LoginGameCenterBody + { + public string code; + public Verification verification; + public User user; + + [Serializable] + public class Verification + { + public Player player; + public Response response; + } + + [Serializable] + public class Player + { + public string bundleId; + public string teamPlayerId; + } + + [Serializable] + public class Response + { + public string signature; + public string salt; + public string publicKeyUrl; + public string timestamp; + } + + [Serializable] + public class User + { + public string id; + } + } +} \ No newline at end of file diff --git a/Assets/Stash/Scripts/Models/LoginGameCenterBody.cs.meta b/Assets/Stash/Scripts/Models/LoginGameCenterBody.cs.meta new file mode 100644 index 0000000..d079bc1 --- /dev/null +++ b/Assets/Stash/Scripts/Models/LoginGameCenterBody.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b368efddc6484b8f99d53ca3123d2f0f +timeCreated: 1720384049 \ No newline at end of file diff --git a/Assets/Stash/Scripts/Models/LoginGooglePlayGamesBody.cs b/Assets/Stash/Scripts/Models/LoginGooglePlayGamesBody.cs new file mode 100644 index 0000000..d67e325 --- /dev/null +++ b/Assets/Stash/Scripts/Models/LoginGooglePlayGamesBody.cs @@ -0,0 +1,18 @@ +using System; + +namespace Stash.Models +{ + [Serializable] + public class LoginGooglePlayGamesBody + { + public string code; + public string authCode; + public User user; + + [Serializable] + public class User + { + public string id; + } + } +} \ No newline at end of file diff --git a/Assets/Stash/Scripts/Models/LoginGooglePlayGamesBody.cs.meta b/Assets/Stash/Scripts/Models/LoginGooglePlayGamesBody.cs.meta new file mode 100644 index 0000000..4126b5f --- /dev/null +++ b/Assets/Stash/Scripts/Models/LoginGooglePlayGamesBody.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 63787ad47813411696289c8499bde4e5 +timeCreated: 1720384216 \ No newline at end of file diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset index 1a4e4b6..8fac5b7 100644 --- a/ProjectSettings/EditorBuildSettings.asset +++ b/ProjectSettings/EditorBuildSettings.asset @@ -6,6 +6,6 @@ EditorBuildSettings: serializedVersion: 2 m_Scenes: - enabled: 1 - path: Assets/Sample/Scenes/StashSample.unity + path: Assets/Stash.Sample/Scenes/StashSample.unity guid: 9fc0d4010bbf28b4594072e72b8655ab m_configObjects: {} diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index c8e7fc5..2bb58fe 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -251,7 +251,7 @@ PlayerSettings: clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea templatePackageId: com.unity.template.3d@8.1.1 templateDefaultScene: Assets/Scenes/SampleScene.unity - useCustomMainManifest: 1 + useCustomMainManifest: 0 useCustomLauncherManifest: 0 useCustomMainGradleTemplate: 0 useCustomLauncherGradleManifest: 0