Apple SignIn with Parse Server - javascript

My App is hosted on sashido.io, which offers Parse Server Hosting. Since it is required, I am trying to implement Apple SignIn for my app. As a first step, I've added the following code to my app. The Apple SignIn works, I get the token and the id, but I cannot create a Parse User with this data. This is my iOS-Code:
var authData = [String: String]()
authData["id"] = id
authData["token"] = token
PFUser.logInWithAuthType(inBackground: "apple", authData: authData).continueWith(block: {
task -> Void in
...
})
I have verified that the authData contains the id and the token properly. Unfortunately, I get an internal server error as response {"code":1,"message":"Internal server error."}
After that, I have modified the following part of my index.js file like this and pushed it to sashido. Unfortunately, this didn't change anything and I'm still getting the internal server error.
var api = new ParseServer(
{
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
appId: process.env.APP_ID || 'myAppId',
masterKey: process.env.MASTER_KEY || 'masterKey',
serverURL: process.env.SERVER_URL || 'http://localhost:' + port + '/1',
// If you change the cloud/main.js to another path
// it wouldn't work on SashiDo :( ... so Don't change this.
cloud: process.env.CLOUD_CODE_MAIN || 'cloud/main.js',
auth: {
apple: {
client_id: process.env.IOS_BUNDLE_ID
}
},
liveQuery: {
classNames: []
},
});

Sign in with Apple support was initially released in Parse Server 3.5.0. However significant improvements and bug fixes have been made subsequently in 3.7.0, 3.8.0 and 4.2.0.
The latest version supported by Sashido is 3.6.0, however they haven't added support for Sign in with Apple yet. See the screenshot below from app settings > users > social login on 3.6.0...
Please also be aware that editing your index.js file and pushing it to your private Sashido GitHub repo will not change the Parse Server config. This facility is purely intended for local development use.
I would suggest you contact Sashido and ask them to add support for Sign in with Apple - ideally on Parse Server 4.2.0 this way you will get the latest improvements.

Related

Use git credential manager to fetch azure devops api instead of personal access token

I am trying to fetch git azure devops api to get information about repositories and branches in js.
In order to achieve that, I made a little application with the following code :
$(document).ready(function() {
var personalToken = btoa(':'+'<personnalAccessToken>');
fetch('https://dev.azure.com/<company>/<project>/_apis/git/repositories?api-version=5.1', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
'Authorization': 'Basic '+ personalToken
}
}).then(function(response) {
return response.json();
}).then(function(repositories) {
console.log("There are "+repositories.count+" repositories");
}).catch(function(error) {
console.log('Fetch error: ' + error.message);
});
This code is working great but as you can see there is my personnalAccessToken writen directly inside the code... which is really bad...
When I am using git in command line, I don't have to specify any credential information because I use git credential manager for windows. Which means my personnalAccessToken is already stored, cached and automatically used everytime I use a git command, like clone, etc.
So, I would like my js code to use the same thing, I would like it to use my stored credentials automatically to fetch the api without being required to set my personnalAccessToken in code.
I have already searched for hours but can't find out if it is possible.
I have already searched for hours but can't find out if it is
possible.
Sorry but as I know it's impossible. The way you're calling the Rest API is similar to use Invoke-RestMethod to call rest api in Powershell.
In both these two scenarios, the process will try to fetch PAT for authentication in current session/context and it won't even try to search the cache in Git Credential Manager.
You should distinguish the difference between accessing Azure Devops service via Rest API and by Code:
Rest API:
POST https://dev.azure.com/{organization}/{project}/{team}/_apis/wit/wiql?api-version=5.1
Request Body:
{
"query": "Select [System.Id], [System.Title], [System.State] From WorkItems Where [System.WorkItemType] = 'Task' AND [State] <> 'Closed' AND [State] <> 'Removed' order by [Microsoft.VSTS.Common.Priority] asc, [System.CreatedDate] desc"
}
Corresponding Code in C#:
VssConnection connection = new VssConnection(new Uri(azureDevOpsOrganizationUrl), new VssClientCredentials());
//create http client and query for resutls
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
Wiql query = new Wiql() { Query = "SELECT [Id], [Title], [State] FROM workitems WHERE [Work Item Type] = 'Bug' AND [Assigned To] = #Me" };
WorkItemQueryResult queryResults = witClient.QueryByWiqlAsync(query).Result;
Maybe you can consider using a limited PAT, limit its scope to Code only:
I know there exists other Authentication mechanism
:
For Interactive JavaScript project: ADALJS and Microsoft-supported Client Libraries.
You can give it a try but I'm not sure if it works for you since you're not using real Code way to access the Azure Devops Service... Hope it makes some help :)
If you have the script set up in an Azure Runbook you can set it as an encrypted variable there and have it pull it from there before running rather than having it directly written into the code.
$encryptedPatVarName = "ADO_PAT"
$adoPat = Get-AutomationVariable -Name $encryptedPatVarName
$adoPatToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($adoPat)"))
$adoHeader = #{authorization = "Basic $adoPatToken"}
The above is the Powershell version of it. I have seen some people do it with other

Google SignIn SDK is failing by throwing error, A non-recoverable sign in failure occurred -catch error: React Native

I have been trying to integrate Social login in my react native project in which I was able to do facebook login successfully but it is failing to signin to google. react-native-google-signin library is used for google.
The code I have used.
componentDidMount() {
GoogleSignin.hasPlayServices({ autoResolve: true }).then(() => {
// play services are available. can now configure library
}).catch((err) => {
console.log("Play services error", err.code, err.message);
})
GoogleSignin.configure({
scopes: ["https://www.googleapis.com/auth/drive.readonly"], // what API you want to access on behalf of the user, default is email and profile
// iosClientId: <FROM DEVELOPER CONSOLE>, // only for iOS
webClientId: "xxx", // client ID of type WEB for your server (needed to verify user ID and offline access)
// offlineAccess: true // if you want to access Google API on behalf of the user FROM YOUR SERVER
//hostedDomain: '' // specifies a hosted domain restriction
//forceConsentPrompt: true // [Android] if you want to show the authorization prompt at each login
//accountName: '' // [Android] specifies an account name on the device that should be used
})
.then(() => {
// you can now call currentUserAsync()
});
_signIn = async () => {
try {
await GoogleSignin.hasPlayServices(
)
const userInfo = await GoogleSignin.signIn();
console.log('User Info --> ', userInfo);
this.setState({ userInfo });
} catch (error) {
console.log('Message', error.message);
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log('User Cancelled the Login Flow');
} else if (error.code === statusCodes.IN_PROGRESS) {
console.log('Signing In');
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log('Play Services Not Available or Outdated');
} else {
console.log('Some Other Error Happened');
}
}
};
The error response:
Message: A non-recoverable sign in failure occurred -catch error
I know, I am very late to answer this question. I just faced the same issue and spent almost 4-5 hours to resolve this.
The solution that I have found:
"It starts working when I have added Support Email on Firebase"
I think it's not the app or configuration issue. It may be a firebase issue that should be reported and nowhere in the doc.
Apk link https://drive.google.com/file/d/1FNFBX-M7PQC6ShCC3KSuOH2E57YGPj6H/view?usp=sharing
go to android folder ./gradlew signingReport Take the SHA1 of Task
:app:signingReport, Variant: debugAndroidTest, Config: debug Update
add fingure print sha1 in your project inside firebae.console.google.com
and download again google-service.json file in your project
[Error: A non-recoverable sign in failure occurred]
1. add support email to solve this error
2. and wait 5 minutes your google login will be working fine
Following here
cd ./android && ./gradlew signingReport
Take the SHA1 of Task :app:signingReport, Variant: debugAndroidTest, Config: debug
Update it the Firebase Console under Project Settings, Android app, add the SHA1
Download the google-services.json, put it in ./android/app
Go to Authentication, then Sign-in method, then press Google
Take the Web client ID and use that for your GoogleSignin.configure({ webClientId: ... });
This Web client ID should be the same as listed in https://console.developers.google.com/apis/credentials?project=<your_project_id> -> Credentials -> OAuth 2 Client ID -> Web Client
run gradlew signingReport in the android folder and check all the sha1 listed and if you are using firebase then make sure that all the distinct sha1 found in the list is added to the firebase project then download the google-services.json again replace it with the old one in you project and run cd android && gradlew clean and build your project again
That's due to the clientId.
In google developer console, When you configure the project for webClientID, instead of creating a new project choose an existing one, i.e create the project first and then choose it for creating credentials.
Create a new project first as of in below picture
then choose that project from the list to create credentials
It worked for me.
And coming to sign in configuration
GoogleSignin.hasPlayServices({ autoResolve: true }).then(() => {
})
.catch((err) => {
console.log("Play services error", err.code, err.message);
})
GoogleSignin.configure({
scopes: ["https://www.googleapis.com/auth/userinfo.profile"],//scopes as you need
webClientId: "***(Your clientId)",
//iosClientId: <FROM DEVELOPER CONSOLE>, // only for iOS
//offlineAccess: true, //(give it true if you need serverAuthCode i.e cross client authorisation)
//hostedDomain: ''
//forceConsentPrompt: true // [Android] if you want to show the authorization prompt at each login
//accountName: ''
})
You need to add the support email.
For that:-
Go to console.firebase.google.com
Select <YOUR_PROJECT> project.
Go to project settings
Under General tab scoll down to add support email. Add your email over there.
In my case, I've used the package name for my test app (ex. com.loginTest). After making my package name unique, I was able to solve this problem!
I searches and came across the following steps
Enable OAuth on https://console.developers.google.com
Copy and paste your SH1 while enabling
Enable Google sign in on firebase authentication
Use Oauth Client_Id instead of your WebClient ID
This fix could also help:
Go to console.developer.google.com
Select the project.
Go to Credentials.
Switch to O Auth Consent screen.
Change the app name and fill email id (optional)
Save at the bottom
Try logging in now and it should work.
Add support email in firebase and it will start working
Android
Make sure to follow these guidlines:
https://rnfirebase.io/auth/social-auth#google
https://github.com/react-native-google-signin/google-signin/blob/master/docs/android-guide.md
Dont forget to generate SHA-Keys and set them in your Firebase Console
with Simulator:
When testing on an Android Simulator, make sure GooglePlayServices are enabled.
To prove this, add a few more lines to your SignInMethod:
const signInWithGoogle = async() => {
// Wrap with try catch
try {
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true }); // <-- Add this
const { idToken } = await GoogleSignin.signIn();
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
return auth().signInWithCredential(googleCredential);
} catch (error) {
// This will show you if GooglePlayServices is missing
console.log('With high probability, GooglePlayServices are missing on this device');
return;
}
}
The problem can reside in the app name, change it to a random (or unique) one (a name you're sure nobody else chosen), or generate a new app with a random (or unique) name.
This is because the generated React Native apps come all with the same SHA-1 fingerprint, and because Google prevents that two different Android apps registered on their cloud share the same pair of App name and SHA-1 fingerprint, you got this error (and surely you have already seen a warning on the Firebase console when creating the App!).
Source: https://support.googles.ltd/firebase/answer/6401008?hl=en&ref_topic=6399725
A complete guide to use Google signin on a React Native app: https://github.com/ubugnu/reactnative-google-signin
i don't know why but i got this error on emulator with Android 28
when i create another emulator with api 31 the error fixed!
IF YOUR APP ARE ON RELEASE:
On project, go to /android, then run ./gradlew signingReport
Copy SHA1 of release and debugTest (very important)
Go to https://console.firebase.google.com
Place all SHA1
Download Google Services JSON and put it on android/app
Build your app and run!
This worked for me.

Microsoft Graph API - 403 Forbidden for v1.0/me/events

I'm building a page with numerous calls to Microsoft Graph to different end points: to get OneDrive files, emails, user properties, etc.
The one call that does not work is to get the current user's calendar events. The end point I'm using is https://graph.microsoft.com/v1.0/me/events. The response is 403 Forbidden.
According to the Microsoft documentation here the application needs Calendars.Read or Calendars.ReadWrite permissions. I checked both of these under delegated permissions and still the same problem. I then ticked all 51 permission scopes in Azure AD for this app, and still the same problem.
I also tried creating a new app in Azure AD, but this did not help.
How can I use Microsoft Graph to get back the current user's calendar events? What am I missing?
EDIT:
I'm using ADAL.js for authentication. This is the code I have in my own doAuth function that takes in the client ID of the application.
function doAuth(clientId) {
var variables = {
// Domain of Azure AD tenant
azureAD: // the appropriate URL,
// ClientId of Azure AD application principal
clientId: clientId,
// Name of SharePoint tenant
sharePointTenant: // the appropriate URL
}
// Create config and get AuthenticationContext
window.config = {
tenant: variables.azureAD,
clientId: variables.clientId,
postLogoutRedirectUri: window.location.origin,
endpoints: {
graphApiUri: "https://graph.microsoft.com",
sharePointUri: "https://" + variables.sharePointTenant + ".sharepoint.com",
},
cacheLocation: "localStorage"
}
var authContext = new AuthenticationContext(config);
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
var user = authContext.getCachedUser();
var token = authContext.getCachedToken(clientId);
if (!user || !token)
authContext.login();
return authContext
}
It sounds like you've changed the scopes assigned to the application. When this happens you also need to have user's reauthorize using those new scopes. To do this, add &prompt=consent to the query string of your initial ODATA redirect. This will force your new scopes to be presented to the user for authorization.
You can trigger this in the ADAL.js library using the extraQueryParameter parameter in your configuration:
// Create config and get AuthenticationContext
window.config = {
tenant: variables.azureAD,
clientId: variables.clientId,
postLogoutRedirectUri: window.location.origin,
endpoints: {
graphApiUri: "https://graph.microsoft.com",
sharePointUri: "https://" + variables.sharePointTenant + ".sharepoint.com",
},
cacheLocation: "localStorage",
extraQueryParameter: "prompt=consent"
}
In the end I wasn't able to figure this out and ended up using the Exchange API instead of Graph for mail, calendar and tasks (tasks would have required Exchange API anyway, since this is only currently available in the beta Graph API).

Facebook Javascript SDK: Can't load a page's public feed [duplicate]

I'm trying to use the Facebook Graph API to get the latest status from a public page, let's say http://www.facebook.com/microsoft
According to http://developers.facebook.com/tools/explorer/?method=GET&path=microsoft%2Fstatuses - I need an access token. As the Microsoft page is 'public', is this definitely the case? Is there no way for me to access these public status' without an access token?
If this is the case, how is the correct method of creating an access token for my website? I have an App ID, however all of the examples at http://developers.facebook.com/docs/authentication/ describe handling user login. I simply want to get the latest status update on the Microsoft page and display it on my site.
This is by design. Once it was possible to fetch the latest status from a public page without access token. That was changed in order to block unidentified anonymous access to the API. You can get an access token for the application (if you don't have a Facebook application set for your website - you should create it) with the following call using graph API:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&
grant_type=client_credentials
This is called App Access Token. Then you proceed with the actual API call using the app access token from above.
hope this helps
You can use AppID and Secret key to get the public posts/feed of any page. This way you don't need to get the access-token. Call it like below.
https://graph.facebook.com/PAGE-ID/feed?access_token=APP-ID|APP-SECRET
And to get posts.
https://graph.facebook.com/PAGE-ID/posts?access_token=APP-ID|APP-SECRET
It's no more possible to use Facebook Graph API without access token for reading public page statuses, what is called Page Public Content Access in Facebook API permissions. Access token even is not enough. You have to use appsecret_proof along with the access token in order to validate that you are the legitimate user. https://developers.facebook.com/blog/post/v2/2018/12/10/verification-for-individual-developers/.
If you are individual developer, you have access to three pages of the data (limited), unless you own a business app.
You can get the posts by simply requesting the site that your browser would request and then extracting the posts from the HTML.
In NodeJS you can do it like this:
// npm i request cheerio request-promise-native
const rp = require('request-promise-native'); // requires installation of `request`
const cheerio = require('cheerio');
function GetFbPosts(pageUrl) {
const requestOptions = {
url: pageUrl,
headers: {
'User-Agent': 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0'
}
};
return rp.get(requestOptions).then( postsHtml => {
const $ = cheerio.load(postsHtml);
const timeLinePostEls = $('.userContent').map((i,el)=>$(el)).get();
const posts = timeLinePostEls.map(post=>{
return {
message: post.html(),
created_at: post.parents('.userContentWrapper').find('.timestampContent').html()
}
});
return posts;
});
}
GetFbPosts('https://www.facebook.com/pg/officialstackoverflow/posts/').then(posts=>{
// Log all posts
for (const post of posts) {
console.log(post.created_at, post.message);
}
});
For more information and an example of how to retrieve more than 20 posts see: https://stackoverflow.com/a/54267937/2879085
I had a similar use case for some weeks and I used this API:
https://rapidapi.com/axesso/api/axesso-facebook-data-service/
I could fetch all posts and comments in some minutes, worked quite well for me.

Invalid appsecret_proof - why?

So, I'm building a new app, using the Javascript API to log in (v2.4), and the latest version (v5) of the PHP API. I created a Test App for it, and am working with that. Using the Javascript API, I do the login and authentication, and save the access token that I get back from getLoginStatus:
FB.getLoginStatus(function(response) {
handleLoginStatusChange(response);
});
function handleLoginStatusChange(response)
{
. . .
else if (response.status == 'connected')
{
// make ajax call to save access token
. . .
}
Then, inside my PHP code, I pick up that access token, and try to use it. I calculate an appsecret_proof, as well.:
$this->fb = new Facebook\Facebook([
'app_id' => <my app id>,
'app_secret'=> <my app secret>,
'default_graph_version' => 'v2.3'
]);
$this->fbApp = new Facebook\FacebookApp( <my app id>,
<my app secret );
$appsecret_proof = hash_hmac('sha256', <access token>,
<app secret>);
Then I try to post a link to my FB account:
$linkData = [
'link' => 'https://google.com',
'message' => 'This is a test post',
];
$response = $this->fb->post('/me/feed', $linkData, <access token>);
This gives me the dreaded " Invalid appsecret_proof provided in the API argument" error. I don't know if this is the problem, but if I put the access token into the debugger, it tells me that this access token is for my actual app, not my test app, so the appID's don't match. I don't think that's a problem, if I understand test apps, especially because I am using the test appID and test appSecret all through this code.
Any ideas? I see several things here on StackOverflow, but they either are older versions of the API, or talk of editing the API code itself to disable things.
it tells me that this access token is for my actual app, not my test app, so the appID's don't match
That is why it does not work.
Think about what happens on Facebook’s side: They need the app secret that was used to calculate the app-secret proof, so they have to look that up via the app id. And where do they get that app id from? From the access token …!
So if you pass an access token for a different app, that will make them use the wrong app secret to calculate the app-secret proof – and so it will not match the value that you sent.
You need to use an access token that belongs to your test app.
(And the PHP SDK takes care of calculating and sending the app secret proof itself, you don’t need to handle that manually.)

Categories

Resources