diff --git a/.gitignore b/.gitignore index 9f6bfb5..3f1e0c0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,15 @@ .settings Referenced Packages salesforce.schema +src/applications/standard__AppLauncher.app +src/applications/standard__Chatter.app +src/applications/standard__Community.app +src/applications/standard__Marketing.app +src/applications/standard__Platform.app +src/applications/standard__Sales.app +src/applications/standard__Service.app +src/applications/standard__ServiceConsole.app +src/applications/standard__Sites.app src/classes/ChangePasswordController.cls src/classes/ChangePasswordController.cls-meta.xml src/classes/ForgotPasswordController.cls diff --git a/OlderChanges.md b/OlderChanges.md new file mode 100644 index 0000000..b613650 --- /dev/null +++ b/OlderChanges.md @@ -0,0 +1,28 @@ +## Changes in version 3.3 + +* Added `FacebookCallback` page and associated controller to handle callback from Facebook centrally. +* Added `FacebookCheckUser` custom Visualforce component and associated controller to periodically check that the current user has a valid Facebook session, and log them out of the Force.com app if the Facebook session is no longer valid. Usage: + + + + + + +* Added `FacebookMessage` and `FacebookThread` classes - wrap [Message](https://developers.facebook.com/docs/reference/api/message/) and [Thread](https://developers.facebook.com/docs/reference/api/thread/) Graph API Objects. +* Added `FacebookInbox` page and associated controller to show how to view Facebook Messages with the Toolkit. Note that there is no mechanism for apps to *send* Facebook Messages. +* Refactored `FacebookSamplePage` to no longer automatically log the user in. Added a login button, and use of the `FacebookCheckUser` custom component. The previous auth-login functionality can be restored by overriding `FacebookLoginController.getAutoLogin()` to return `false`. +* Added optional `title` attribute to the `FacebookProfilePicture` custom component to specify tooltip text for the image. +* Added new `FacebookToolkitPage`, collecting the sample, user connections and inbox pages into a tab panel. + +## Changes in version 3.2 + +* Secured the Facebook application client secret and user access tokens by encrypting with a key stored as a custom setting. + +## Changes in version 3.1 + +* Minor fixes plus Authentication Providers support. + +## Major changes in Version 3 + +* There is a new custom object, `FacebookSession__c`, that associates the Facebook access token with a session cookie. This allows a Force.com Site to authenticate users via Facebook. +* The toolkit uses the new native JSON implementation, mitigating issues in earlier versions where JSON was parsed in an Apex utility class, which severely limited the amount of data that could be parsed. diff --git a/README.md b/README.md index b28256c..b68bfa8 100644 --- a/README.md +++ b/README.md @@ -4,34 +4,14 @@ The Force.com Toolkit for Facebook allows your Force.com apps to manipulate the There is a sample deployment of the toolkit at https://testfbtk3-developer-edition.na14.force.com/ - you can visit this Force.com Site, login via Facebook, and see the toolkit in action. All the code behind the sample site is included in the toolkit. -## Changes in version 3.3 +## Changes in version 3.4 -* Added `FacebookCallback` page and associated controller to handle callback from Facebook centrally. -* Added `FacebookCheckUser` custom Visualforce component and associated controller to periodically check that the current user has a valid Facebook session, and log them out of the Force.com app if the Facebook session is no longer valid. Usage: +* Added sample code to FacebookInboxPage to show how to send Facebook Messages using the [Facebook SDK for JavaScript](https://developers.facebook.com/docs/javascript) +* Better error handling during OAuth flow +* Access Token field in Facebook Session object is now 1024 bytes +* Updated Permissions picklist in Facebook App to match [Facebook Permissions Reference](https://developers.facebook.com/docs/facebook-login/permissions) - - - - - -* Added `FacebookMessage` and `FacebookThread` classes - wrap [Message](https://developers.facebook.com/docs/reference/api/message/) and [Thread](https://developers.facebook.com/docs/reference/api/thread/) Graph API Objects. -* Added `FacebookInbox` page and associated controller to show how to view Facebook Messages with the Toolkit. Note that there is no mechanism for apps to *send* Facebook Messages. -* Refactored `FacebookSamplePage` to no longer automatically log the user in. Added a login button, and use of the `FacebookCheckUser` custom component. The previous auth-login functionality can be restored by overriding `FacebookLoginController.getAutoLogin()` to return `false`. -* Added optional `title` attribute to the `FacebookProfilePicture` custom component to specify tooltip text for the image. -* Added new `FacebookToolkitPage`, collecting the sample, user connections and inbox pages into a tab panel. - -## Changes in version 3.2 - -* Secured the Facebook application client secret and user access tokens by encrypting with a key stored as a custom setting. - -## Changes in version 3.1 - -* Minor fixes plus Authentication Providers support. - -## Major changes in Version 3 - -* There is a new custom object, `FacebookSession__c`, that associates the Facebook access token with a session cookie. This allows a Force.com Site to authenticate users via Facebook. -* The toolkit uses the new native JSON implementation, mitigating issues in earlier versions where JSON was parsed in an Apex utility class, which severely limited the amount of data that could be parsed. +[Older Changes](OlderChanges.md) ## Installation @@ -40,9 +20,8 @@ There are two mechanisms for installing the toolkit: as an unmanaged package, or ### Installing the Unmanaged Package 1. Create a new Developer Edition (DE) account at http://developer.force.com/join. You will receive an activation email - click the enclosed link to complete setup of your DE environment. This will also log you in to your new DE environment. -2. Install the unmanaged package into your new DE org via this URL: https://login.salesforce.com/packaging/installPackage.apexp?p0=04td00000001LuM +2. Install the unmanaged package into your new DE org via this URL: https://login.salesforce.com/packaging/installPackage.apexp?p0=04td00000001q8m 3. Click through the screens to complete installation. -4. Go to **Setup | Administration Setup | Security Controls | Remote Site Settings** and add https://graph.facebook.com as a new remote site. ### Installing from GitHub @@ -85,14 +64,9 @@ Your controller code can now retrieve the current user's token with `FacebookTok ### Map Facebook Accounts to Salesforce Users -Alternatively, from Spring ''12 onwards, you can implement your app within a Salesforce org or portal. In this case, each Facebook account is mapped to a unique user within your Salesforce org. [Social Single Sign-On – Authentication Providers in Spring ’12](http://blogs.developerforce.com/developer-relations/2012/01/social-single-sign-on-authentication-providers-in-spring-12.html) gives an overview of configuring Facebook as an *Authentication Provider* and linking existing salesforce.com users'' accounts to their Facebook accounts, or creating new accounts for users arriving from Facebook. - -If you are using the Facebook Authentication Provider, you need not use `FacebookLoginController`; the platform will manage interaction with Facebook for you. Your Apex code can retrieve the current user''s token with `Auth.AuthToken.getAccessToken(AuthProviderID, AuthProviderType);`. - -Since the main intent of this first, Spring ''12, release of Authentication Provider functionality is to provide single sign-on and account linking, there are some limitations in using the FB access token with the Graph API: +Alternatively, from Spring ’12 onwards, you can implement your app within a Salesforce org or portal. In this case, each Facebook account is mapped to a unique user within your Salesforce org. [Social Single Sign-On – Authentication Providers in Spring ’12](http://blogs.developerforce.com/developer-relations/2012/01/social-single-sign-on-authentication-providers-in-spring-12.html) gives an overview of configuring Facebook as an *Authentication Provider* and linking existing salesforce.com users’ accounts to their Facebook accounts, or creating new accounts for users arriving from Facebook. -* The Facebook Authentication Provider requests only the `email` permission, limiting the amount of data you can retrieve via the Graph API to the user's email address, user id, name, profile picture, gender, age range, locale, networks, list of friends, and any other information they have made public. It is expected that developers will be able to set a custom set of requested permissions in a future release. -* The Facebook access token will expire after two hours. There is currently no mechanism for obtaining a fresh access token. One possible strategy for handling this issue would be to detect token expiry and offer to redirect the user to the Authentication Provider SSO link to reauthenticate to Salesforce. +If you are using the Facebook Authentication Provider, you need not use `FacebookLoginController`; the platform will manage interaction with Facebook for you. Your Apex code can retrieve the current user’s token with `Auth.AuthToken.getAccessToken(AuthProviderID, AuthProviderType);`. ### Accessing the Graph API diff --git a/src/classes/FacebookCallbackController.cls b/src/classes/FacebookCallbackController.cls index 480cc3b..a1428cb 100644 --- a/src/classes/FacebookCallbackController.cls +++ b/src/classes/FacebookCallbackController.cls @@ -1,7 +1,19 @@ public with sharing class FacebookCallbackController extends FacebookLoginController { // Page initialization - handle FB authorization code - public override PageReference init() { - if (! ApexPages.currentPage().getParameters().containsKey('code')) { + public override PageReference init() { + if (ApexPages.currentPage().getParameters().containsKey('error_code')) { + ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, + 'error_code=' + ApexPages.currentPage().getParameters().get('error_code'))); + ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, + ApexPages.currentPage().getParameters().get('error_message'))); + return null; + } else if (ApexPages.currentPage().getParameters().containsKey('error')) { + ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, + ApexPages.currentPage().getParameters().get('error'))); + ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, + ApexPages.currentPage().getParameters().get('error_description'))); + return null; + } else if (! ApexPages.currentPage().getParameters().containsKey('code')) { ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.FATAL, 'Missing code parameter'); ApexPages.addMessage(msg); return null; diff --git a/src/objects/EncryptionSettings__c.object b/src/objects/EncryptionSettings__c.object index e28a086..60be541 100644 --- a/src/objects/EncryptionSettings__c.object +++ b/src/objects/EncryptionSettings__c.object @@ -1,7 +1,6 @@ Hierarchy - Protected Encryption key for private data. Set on first use. false @@ -11,8 +10,10 @@ 255 true + false Text false + Protected diff --git a/src/objects/FacebookApp__c.object b/src/objects/FacebookApp__c.object index 724d9b8..d5c9e48 100644 --- a/src/objects/FacebookApp__c.object +++ b/src/objects/FacebookApp__c.object @@ -4,6 +4,10 @@ Accept Default + + CancelEdit + Default + Clone Default @@ -16,6 +20,10 @@ Edit Default + + Follow + Default + List Default @@ -24,6 +32,10 @@ New Default + + SaveEdit + Default + Tab Default @@ -32,12 +44,18 @@ View Default + false + SYSTEM Deployed false + true false true false false + true + true + true clientID__c false @@ -46,6 +64,7 @@ 255 true false + false Text false @@ -57,6 +76,7 @@ 255 false false + false Text false @@ -67,95 +87,11 @@ - user_about_me - false - - - user_activities - false - - - user_birthday - false - - - user_checkins - false - - - user_education_history - false - - - user_events - false - - - user_groups - false - - - user_hometown + public_profile false - user_interests - false - - - user_likes - false - - - user_location - false - - - user_notes - false - - - user_online_presence - false - - - user_photo_video_tags - false - - - user_photos - false - - - user_questions - false - - - user_relationships - false - - - user_relationship_details - false - - - user_religion_politics - false - - - user_status - false - - - user_videos - false - - - user_website - false - - - user_work_history + user_friends false @@ -163,99 +99,95 @@ false - friends_about_me - false - - - friends_activities + user_about_me false - friends_birthday + user_actions.books false - friends_checkins + user_actions.fitness false - friends_education_history + user_actions.music false - friends_events + user_actions.news false - friends_groups + user_actions.video false - friends_hometown + user_birthday false - friends_interests + user_education_history false - friends_likes + user_events false - friends_location + user_games_activity false - friends_notes + user_hometown false - friends_online_presence + user_likes false - friends_photo_video_tags + user_location false - friends_photos + user_managed_groups false - friends_questions + user_photos false - friends_relationships + user_posts false - friends_relationship_details + user_relationships false - friends_religion_politics + user_relationship_details false - friends_status + user_religion_politics false - friends_videos + user_tagged_places false - friends_website + user_videos false - friends_work_history + user_website false - read_friendlists + user_work_history false @@ -263,64 +195,41 @@ false - read_mailbox - false - - - read_requests - false - - - read_stream - false - - - xmpp_login - false - - - ads_management - false - - - create_event - false - - - manage_friendlists + read_page_mailboxes false - manage_notifications + manage_pages false - offline_access + publish_pages false - publish_checkins + publish_actions false - publish_stream + rsvp_event false - rsvp_event + ads_read false - publish_actions + ads_management false - manage_pages + read_friendlists false false false + false MultiselectPicklist 10 diff --git a/src/objects/FacebookSession__c.object b/src/objects/FacebookSession__c.object index 64db1dd..1d6d8b6 100644 --- a/src/objects/FacebookSession__c.object +++ b/src/objects/FacebookSession__c.object @@ -4,6 +4,10 @@ Accept Default + + CancelEdit + Default + Clone Default @@ -16,6 +20,10 @@ Edit Default + + Follow + Default + List Default @@ -24,6 +32,10 @@ New Default + + SaveEdit + Default + Tab Default @@ -32,26 +44,33 @@ View Default + false + SYSTEM Deployed false + true false false false false + true + true + true AccessToken__c false - 255 - true - Text - false + 1024 + false + LongTextArea + 2 Expiry__c false true + false DateTime @@ -60,6 +79,7 @@ 120 true + false Text false diff --git a/src/pages/FacebookAppSecret.page-meta.xml b/src/pages/FacebookAppSecret.page-meta.xml index d4672dd..c58c43d 100644 --- a/src/pages/FacebookAppSecret.page-meta.xml +++ b/src/pages/FacebookAppSecret.page-meta.xml @@ -1,5 +1,7 @@ 24.0 + false + false diff --git a/src/pages/FacebookCallback.page-meta.xml b/src/pages/FacebookCallback.page-meta.xml index 1d23e03..460d1fb 100644 --- a/src/pages/FacebookCallback.page-meta.xml +++ b/src/pages/FacebookCallback.page-meta.xml @@ -1,5 +1,7 @@ 25.0 + false + false diff --git a/src/pages/FacebookInboxPage.page b/src/pages/FacebookInboxPage.page index 6c28229..0cc0a8e 100644 --- a/src/pages/FacebookInboxPage.page +++ b/src/pages/FacebookInboxPage.page @@ -4,11 +4,37 @@

This page shows you how to view your Facebook Messages with the Force.com Toolkit for Facebook. Note that there is no mechanism for - apps to send Facebook Messages.

+ apps to send Facebook Messages via the Graph API. Click a user's photo + in the left column to send a message using the Facebook JavaScript SDK.

Your Inbox

   @@ -17,7 +43,9 @@ - + + + diff --git a/src/pages/FacebookInboxPage.page-meta.xml b/src/pages/FacebookInboxPage.page-meta.xml index da11b04..4b070ce 100644 --- a/src/pages/FacebookInboxPage.page-meta.xml +++ b/src/pages/FacebookInboxPage.page-meta.xml @@ -1,5 +1,7 @@ 25.0 + false + false diff --git a/src/pages/FacebookSamplePage.page-meta.xml b/src/pages/FacebookSamplePage.page-meta.xml index 3d295bd..bbbed45 100644 --- a/src/pages/FacebookSamplePage.page-meta.xml +++ b/src/pages/FacebookSamplePage.page-meta.xml @@ -1,5 +1,7 @@ 23.0 + false + false diff --git a/src/pages/FacebookTestUser.page-meta.xml b/src/pages/FacebookTestUser.page-meta.xml index e318a47..194177b 100644 --- a/src/pages/FacebookTestUser.page-meta.xml +++ b/src/pages/FacebookTestUser.page-meta.xml @@ -1,5 +1,7 @@ 23.0 + false + false diff --git a/src/pages/FacebookToolkitPage.page-meta.xml b/src/pages/FacebookToolkitPage.page-meta.xml index bff4688..fe6fbe2 100644 --- a/src/pages/FacebookToolkitPage.page-meta.xml +++ b/src/pages/FacebookToolkitPage.page-meta.xml @@ -1,5 +1,7 @@ 25.0 + false + false