Requesting Consent For New Permissions
After a player has received a session with permissions, they may want to enable additional permissions. Permissions may be disabled for reasons such as
- They are below the age threshold for the permission to be enabled by default.
- They are below the absolute miniumum required age for the permission.
- The permission can only be enabled with a parent/guardian's consent, and it was not enabled during the consent process.
The /session/upgrade
API
The /session/upgrade
API can be used to enable additional permissions. Any requested permissions which have the managedBy
field set to PLAYER
will be enabled immediately. If there are permissions which have managedBy
set to GUARDIAN
, then a challenge will be created for the parent/guardian to complete in order to consent to the permission change.
Asking for Parental Consent
When parental consent is needed to enable a permission, a challenge
will be included in the response. This challenge can be shared similarly to the initial age gate process, by using a QR code, OTP, or email.
One quality-of-life difference is that it is possible to use the /challenge/send-email
API without specifying an email address, and the API will send an email to the parent/guardian who most recently approved a permission for the player. This enables players to request permission changes without specifying an email address themselves. If no associated email address is found, the /challenge/send-email
API will reply with an INVALID_EMAIL
error code, and you will need to fall back to another method, such as providing a QR code or OTP, or asking the player to enter their parent/guardian's email address.
Examples
// Creates a new consent challenge if the Permission is managed by GUARDIAN, and if successful,
// calls the EnableFeature callback parameter, which can then turn on the feature in the game
void UKidWorkflow::UpgradeSession(const FString &FeatureName, TFunction<void()> EnableFeature)
{
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject());
JsonObject->SetStringField(TEXT("sessionId"), SessionInfo->GetStringField(TEXT("sessionId")));
TSharedPtr<FJsonObject> PermJsonObject = MakeShareable(new FJsonObject());
PermJsonObject->SetStringField(TEXT("name"), FeatureName);
TArray<TSharedPtr<FJsonValue>> JsonArray;
JsonArray.Add(MakeShareable(new FJsonValueObject(PermJsonObject)));
JsonObject->SetArrayField(TEXT("requestedPermissions"), JsonArray);
FString ContentJsonString;
TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&ContentJsonString);
FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer);
HttpRequestHelper::PostRequestWithAuth(BaseUrl + TEXT("/session/upgrade"), ContentJsonString, AuthToken,
[this, EnableFeature, FeatureName](FHttpResponsePtr Response, bool bWasSuccessful)
{
if (bWasSuccessful)
{
TSharedPtr<FJsonObject> JsonResponse;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
if (FJsonSerializer::Deserialize(Reader, JsonResponse))
{
if (JsonResponse->HasField(TEXT("challenge")))
{
TSharedPtr<FJsonObject> Challenge = JsonResponse->GetObjectField(TEXT("challenge"));
FString ChallengeId = Challenge->GetStringField(TEXT("challengeId"));
FString OneTimePassword = Challenge->GetStringField(TEXT("oneTimePassword"));
FString QRCodeUrl = Challenge->GetStringField(TEXT("url"));
SaveChallengeId(ChallengeId);
ShowConsentChallenge(ChallengeId, ConsentTimeoutSeconds, OneTimePassword, QRCodeUrl,
[this, EnableFeature, FeatureName](bool bConsentGranted, const FString &SessionId)
{
ClearChallengeId();
if (bConsentGranted)
{
GetSessionPermissions(SessionId, TEXT(""));
EnableFeature();
}
else
{
// request to turn on feature was denied, don't do anything
UE_LOG(LogTemp, Warning, TEXT("Feature request denied for feature %s."), *FeatureName);
}
});
}
else if (JsonResponse->HasField(TEXT("session")))
{
SessionInfo = JsonResponse->GetObjectField(TEXT("session"));
SaveSessionInfo();
EnableFeature();
}
}
}
});
}