Skip to content

Commit

Permalink
add limited login APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
AGulev committed Apr 9, 2024
1 parent f2c766e commit 719350d
Show file tree
Hide file tree
Showing 3 changed files with 282 additions and 0 deletions.
99 changes: 99 additions & 0 deletions facebook/src/facebook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,97 @@ static int Facebook_DisableAdvertiserTracking(lua_State* L)
#endif
}

static int Facebook_SetDefaultAudience(lua_State* L)
{
#if defined(DM_PLATFORM_IOS)
CHECK_FACEBOOK_INIT(L);
DM_LUA_STACK_CHECK(L, 0);
int audience = luaL_checkinteger(L, 1);
Platform_FacebookSetDefaultAudience(audience);
return 0;
#else
dmLogWarning("`set_default_audience` is iOS only function.");
return 0;
#endif
}

static int Facebook_LoginWithTrackingPreference(lua_State* L)
{
#if defined(DM_PLATFORM_IOS)
CHECK_FACEBOOK_INIT(L);
DM_LUA_STACK_CHECK(L, 0);

int login_tracking = luaL_checkinteger(L, 1);
luaL_checktype(L, 2, LUA_TTABLE);
int type = lua_type(L, 3);
const char* crypto_nonce = 0x0;
if (type == LUA_TSTRING)
{
crypto_nonce = lua_tostring(L, 3);
}
else if (type == LUA_TNIL)
{
// do nothing, it's fine
}
else
{
return luaL_error(L, "`crypto_nonce` should be string or `nil`");
}
dmScript::LuaCallbackInfo* callback = dmScript::CreateCallback(L, 4);

char* permissions[128];
int permission_count = luaTableToCArray(L, 2, permissions, sizeof(permissions) / sizeof(permissions[0]));
if (permission_count == -1)
{
return luaL_error(L, "Facebook permissions must be strings");
}

Platform_FacebookLoginWithTrackingPreference((dmFacebook::LoginTracking)login_tracking, (const char**) permissions, permission_count, crypto_nonce, callback);

for (int i = 0; i < permission_count; ++i)
{
free(permissions[i]);
}
return 0;
#else
dmLogWarning("`login_with_tracking_preference` is iOS only function.");
return 0;
#endif
}

static int Facebook_GetCurrentAuthenticationToken(lua_State* L)
{
#if defined(DM_PLATFORM_IOS)
CHECK_FACEBOOK_INIT(L);
DM_LUA_STACK_CHECK(L, 1);
const char* token = Platform_FacebookGetCurrentAuthenticationToken();
if (token == 0x0)
{
lua_pushnil(L);
}
else
{
lua_pushstring(L, token);
}
return 1;
#else
dmLogWarning("`get_current_authentication_token` is iOS only function.");
return 0;
#endif
}

static int Facebook_GetCurrentProfile(lua_State* L)
{
#if defined(DM_PLATFORM_IOS)
CHECK_FACEBOOK_INIT(L);
DM_LUA_STACK_CHECK(L, 1);
return Platform_FacebookGetCurrentProfile(L);
#else
dmLogWarning("`get_current_profile` is iOS only function.");
return 0;
#endif
}

static const luaL_reg Facebook_methods[] =
{
{"init", Facebook_Init},
Expand All @@ -157,6 +248,11 @@ static const luaL_reg Facebook_methods[] =
{"deferred_deep_link", Facebook_FetchDeferredAppLinkData},
{"enable_advertiser_tracking", Facebook_EnableAdvertiserTracking},
{"disable_advertiser_tracking", Facebook_DisableAdvertiserTracking},
// iOS only function. FB SDK 17.0:
{"set_default_audience", Facebook_SetDefaultAudience},
{"login_with_tracking_preference", Facebook_LoginWithTrackingPreference},
{"get_current_authentication_token", Facebook_GetCurrentAuthenticationToken},
{"get_current_profile", Facebook_GetCurrentProfile},
{0, 0}
};

Expand Down Expand Up @@ -191,6 +287,9 @@ static void LuaInit(lua_State* L)
SETCONSTANT(AUDIENCE_FRIENDS, dmFacebook::AUDIENCE_FRIENDS);
SETCONSTANT(AUDIENCE_EVERYONE, dmFacebook::AUDIENCE_EVERYONE);

SETCONSTANT(LOGIN_TRACKING_LIMITED, dmFacebook::LOGIN_TRACKING_LIMITED);
SETCONSTANT(LOGIN_TRACKING_ENABLED, dmFacebook::LOGIN_TRACKING_ENABLED);

#undef SETCONSTANT

#if defined(DM_PLATFORM_HTML5)
Expand Down
173 changes: 173 additions & 0 deletions facebook/src/facebook_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,17 @@ static FBSDKGameRequestActionType convertGameRequestAction(int fromLuaInt) {
}
}

static FBSDKLoginTracking convertLoginTracking(int fromLuaInt) {
switch (fromLuaInt) {
case dmFacebook::LOGIN_TRACKING_LIMITED:
return FBSDKLoginTrackingLimited;
case dmFacebook::LOGIN_TRACKING_ENABLED:
return FBSDKLoginTrackingEnabled;
default:
return FBSDKLoginTrackingLimited;
}
}

static FBSDKGameRequestFilter convertGameRequestFilters(int fromLuaInt) {
switch (fromLuaInt) {
case 3:
Expand Down Expand Up @@ -616,6 +627,168 @@ int Platform_FacebookInit(lua_State* L)
return 0;
}


void Platform_OnEventFacebook(dmExtension::Params* params, const dmExtension::Event* event)
{
(void)params; (void)event;
}

void Platform_FacebookSetDefaultAudience(int audience)
{
[g_Facebook.m_Login setDefaultAudience: convertDefaultAudience(audience)];
}

void Platform_FacebookLoginWithTrackingPreference(dmFacebook::LoginTracking login_tracking, const char** permissions, uint32_t permission_count, const char* crypto_nonce, dmScript::LuaCallbackInfo* callback)
{
// This function must always return so memory for `permissions` can be free'd.
g_Facebook.m_Delegate.m_Callback = callback;

if (login_tracking == dmFacebook::LOGIN_TRACKING_ENABLED) {
// Check if there already is a access token, and if it has expired.
// In such case we want to reautorize instead of doing a new login.
if ([FBSDKAccessToken currentAccessToken]) {
if ([FBSDKAccessToken currentAccessToken].dataAccessExpired) {
[g_Facebook.m_Login reauthorizeDataAccess:nil handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
LoginCallback(callback, result, error);
}];
return;
}
}
}
NSMutableArray* ns_permissions = [[NSMutableArray alloc] init];
for (uint32_t i = 0; i < permission_count; ++i)
{
const char* permission = permissions[i];
[ns_permissions addObject: [NSString stringWithUTF8String: permission]];
}
FBSDKLoginConfiguration *configuration =
[[FBSDKLoginConfiguration alloc] initWithPermissions:ns_permissions
tracking:convertLoginTracking(login_tracking)
nonce:[NSString stringWithUTF8String:crypto_nonce]];

@try
{
[g_Facebook.m_Login logInFromViewController:nil configuration:configuration completion:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
LoginCallback(callback, result, error);
}];
} @catch (NSException* exception)
{
NSString* errorMessage = [NSString stringWithFormat:@"Unable to request permissions: %@", exception.reason];
dmFacebook::RunStatusCallback(callback, [errorMessage UTF8String], dmFacebook::STATE_CLOSED_LOGIN_FAILED);
}
}

const char* Platform_FacebookGetCurrentAuthenticationToken()
{
if (!FBSDKAuthenticationToken.currentAuthenticationToken)
{
return 0x0;
}
return [FBSDKAuthenticationToken.currentAuthenticationToken.tokenString UTF8String];
}

int Platform_FacebookGetCurrentProfile(lua_State* L)
{
FBSDKProfile *profile = [FBSDKProfile currentProfile];

if (profile) {
#define PUSH_STR(L, field) \
if (profile.field) { \
lua_pushstring(L, [profile.field UTF8String]); \
lua_setfield(L, -2, #field); \
} \

#define PUSH_URL(L, field) \
if (profile.field) { \
lua_pushstring(L, [profile.field.absoluteString UTF8String]); \
lua_setfield(L, -2, #field); \
} \

#define PUSH_TIMESTAMP(L, field) \
if (profile.field) { \
lua_pushnumber(L, [profile.field timeIntervalSince1970]); \
lua_setfield(L, -2, #field); \
} \

#define PUSH_LOCATION(L, field) \
if (profile.field) { \
FBSDKLocation *location_field = profile.field; \
lua_newtable(L); \
lua_pushstring(L, [location_field.id UTF8String]); \
lua_setfield(L, -2, "id"); \
lua_pushstring(L, [location_field.name UTF8String]); \
lua_setfield(L, -2, "name"); \
lua_setfield(L, -2, #field); \
} \

lua_newtable(L);

PUSH_STR(L, userID);
PUSH_STR(L, firstName);
PUSH_STR(L, middleName);
PUSH_STR(L, lastName);
PUSH_STR(L, name);
PUSH_STR(L, email);
PUSH_STR(L, gender);

PUSH_URL(L, linkURL);
PUSH_URL(L, imageURL);

PUSH_TIMESTAMP(L, refreshDate);
PUSH_TIMESTAMP(L, birthday);

PUSH_LOCATION(L, location);
PUSH_LOCATION(L, hometown);

#undef PUSH_URL
#undef PUSH_STR
#undef PUSH_TIMESTAMP
#undef PUSH_LOCATION

FBSDKUserAgeRange *ageRange = profile.ageRange;
if (ageRange) {
lua_newtable(L);
lua_pushnumber(L, [ageRange.min doubleValue]);
lua_setfield(L, -2, "min");
lua_pushnumber(L, [ageRange.max doubleValue]);
lua_setfield(L, -2, "max");
lua_setfield(L, -2, "ageRange");
}

NSSet<NSString *> *permissions = profile.permissions;
if (permissions && permissions.count > 0) {
lua_newtable(L);

int index = 1;
for (NSString *permission in permissions) {
lua_pushstring(L, [permission UTF8String]);
lua_rawseti(L, -2, index);
index++;
}

lua_setfield(L, -2, "permissions");
}

NSArray<FBSDKUserIdentifier> *friendIDs = profile.friendIDs;
if (friendIDs && friendIDs.count > 0) {
lua_newtable(L);

int index = 1;
for (FBSDKUserIdentifier friendID in friendIDs) {
lua_pushstring(L, [friendID UTF8String]);
lua_rawseti(L, -2, index);
index++;
}

lua_setfield(L, -2, "friendIDs");
}
} else {
lua_pushnil(L);
}

return 1; // Number of return values pushed onto the stack
}

dmExtension::Result Platform_AppInitializeFacebook(dmExtension::AppParams* params, const char* app_id)
{
g_Facebook.m_AppId = app_id;
Expand Down
10 changes: 10 additions & 0 deletions facebook/src/facebook_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ namespace dmFacebook {
COMMAND_TYPE_DEFERRED_APP_LINK = 6
};

enum LoginTracking {
LOGIN_TRACKING_LIMITED = 1,
LOGIN_TRACKING_ENABLED = 2
};

struct FacebookCommand
{
FacebookCommand()
Expand Down Expand Up @@ -155,3 +160,8 @@ dmExtension::Result Platform_InitializeFacebook(dmExtension::Params* params);
dmExtension::Result Platform_FinalizeFacebook(dmExtension::Params* params);
dmExtension::Result Platform_UpdateFacebook(dmExtension::Params* params);
void Platform_OnEventFacebook(dmExtension::Params* params, const dmExtension::Event* event);

void Platform_FacebookSetDefaultAudience(int audience);
void Platform_FacebookLoginWithTrackingPreference(dmFacebook::LoginTracking login_tracking, const char** permissions, uint32_t permission_count, const char* crypto_nonce, dmScript::LuaCallbackInfo* callback);
const char* Platform_FacebookGetCurrentAuthenticationToken();
int Platform_FacebookGetCurrentProfile(lua_State* L);

0 comments on commit 719350d

Please sign in to comment.