SAP Fiori Get logged in user details in UI5 application - sapui5

I've a SAP Fiori application and I need to get the current logged in user details.
I've searched web but unable to find a solution.
is there any way to get current logged in user details from launchpad.

There is a UserInfo service from the FLP shell which can be retrieved like this:
{ // In Controller
doSomethingUserDetails: async function() {
const oUserInfo = await this.getUserInfoService();
const sUserId = oUserInfo.getId(); // And in SAPUI5 1.86, those became public: .getEmail(), .getFirstName(), .getLastName(), .getFullName(), ...
// ...
},
getUserInfoService: function() {
return new Promise(resolve => sap.ui.require([
"sap/ushell/library"
], oSapUshellLib => {
const oContainer = oSapUshellLib.Container;
const pService = oContainer.getServiceAsync("UserInfo"); // .getService is deprecated!
resolve(pService);
}));
},
}
To align with the current best practices, avoid calling sap.ushell.Container.getService directly!
getService is deprecated. Use getServiceAsync instead.
Require the library instead of referencing the Container via global namespace (sap.ushell.*) as shown above.
Alternatively, information about the the current user can be also retrieved via the user API service exposed by the application router from the SAP Business Technology Platform (SAP BTP).
* In case the app is deployed to the old Neo environment, see the previous edit.

The User-ID can be retrieved from SDK.
Please refer to class sap.ushell.services.UserInfo

Try this:
new sap.ushell.services.UserInfo().getId()

If you want to access the user detail when you are running your application in launchpad. then you can retrieve current user detail by adding following code snippet:
var userInfo = sap.ushell.Container.getService("UserInfo");
var email = userInfo.getEmail();
Then further detail about the user can be retrieved like email and fullname. See the API here.

Related

Flutter oAuth : how to get started with OAuth and Stripe connect

I am trying to implement stripe connect in my flutter app. Here are the steps I need to implement. Can anyone please navigate me on how I could achieve this in Flutter?
I am able to create a button with the endpointUrl but that's all..
Thanks
I found out this myself using firebase cloud functions:
first you create an https function in the firebase cloud function
then you add the link created by the function to your stripe dashboard
then you write the following logic to your function
obtain the the authorisation code
fetch data from stripe
save the response somewhere (in my case in realtime database)
Here is the function
exports.connectStripeStandardAccount = functions.https.onRequest((req, res) => {
let authCode = req.query.code;
return stripe.oauth.token({
grant_type: 'authorization_code',
code: authCode,
}).then(async response => {
await admin.database()
.ref(`/accounts/${authCode}`)
.set(response);
return res.send("Well done, account integration is completed. You can now close the window and go back to the app");
});
});
The answer selected is not completely correct:
If you dont assign the account_id to a user then it's of no use.
The only way to pass the user_id (fUser.uid) is to pass it using the state parameter.
exports.StripePI = functions.https.onRequest(async (req, res) => {
// console.log('accountIdq ' + req.query.error);
// console.log('accountIdq ' + req.query.state);
// return;
// if(!req.query.code)
// return res.send("An Error has occured please try again");
const response = await stripe.oauth.token({
grant_type: 'authorization_code',
code: req.query.code,
}).then(async response => {
var connected_account_id = response.stripe_user_id;
await admin.firestore().collection('Registration').doc(req.query.state)
.update({customer_id : connected_account_id});
return res.send("Well done, account integration is completed. You can now close the window and go back to the app");
});
});
If you want to create an in-app stripe connect account registration with flutter you will need these:
A server or service to complete the OAuth like Firebase Functions or Integromat (I used Integromat)
A link that will redirect to your app (I used Firebase Dynamic Link)
STEPS TO CREATE THE REGISTRATION FLOW
INTEGROMAT/FIREBASE FUNCTIONS SETUP
I decided to use Integromat instead of Firebase Functions because is easier to set up, doesn't need any code, and decreases my server load.
If you want to create it on Firebase Functions you will need to have a Blaze Plan
If you don't know it, Integromat will automate processes that you currently handle manually, via webhooks. It is not only capable of connecting apps (like GoogleCloud, Facebook, AWS...) but can also transfer and transform data.
Create a new scenario and add a Custom Webhook. Click on it and click on add, name it, and save it. It will now create a custom link to your webhook.
Close and click on the semi-sphere next to the webhook, to add the new module.
Select HTTP and Make a Request.
In the URL section insert https://connect.stripe.com/oauth/token.
Method POST.
Body Type Application/x-www-form-urlencoded.
Create now those fields :
Key client_secret - value your stripe client secret You can find it on your stripe dashboard. I advise you to first use the test mode and after that, change the value to the live key.
Key grant_type - value authorization_code
Key code - leave the value blank. We will add it later.
Save and close
For Firebase Functions you can create a new HTTPS function (I didn't test this)
var stripe = require("stripe")(*your stripe client secret*);
exports.connectStripeStandardAccount = functions.https.onRequest((req, res) =>{
let authCode = req.query.code;
return stripe.oauth.token({
grant_type: 'authorization_code',
code: authCode,
});
});
Remember to install stripe package npm install stripe
STRIPE SETUP
If you are in the test mode go to this link
If you are in the live mode go to this link
Go on the bottom and activate oAuth for standard accounts or for Express Account.
Click on Add URI and add the webhook link of Integromat that you created or the link related to your Firebase function.
If you used Firebase add this link https://us-central1-<project-id>.cloudfunctions.net/connectStripeStandardAccount
For Integromat you will need to create the structure. To do this click on Test OAuth, copy the link, and open it in incognito mode. Open your Integromat scenario and click on your webhook. Now click on Re-determine data structure.
Return to your stripe registration page and click on Ignore account form at the top.
Return on Integromat and select the HTTPS request, modify the field code, and insert the variable code (will open a dialog with all queries from the webhook). Confirm and save.
Now click on the play button and reopen the stripe registration link in incognito mode and click on Ignore account form. Return in Integromat and add a JSON module after the HTTPS request. In the JSON string insert the Data variable and save. Create a Webhook Response module after the JSON module.
In the status put 301, then click on Ok.
DEEP LINK SETUP
It's time to set up the redirect link that will return the user to our flutter app or on our website if the user hasn't it installed.
I used Firebase Dynamic Link You can follow this tutorial for set up.
Go to the dashboard and create a new Link prefix and a new dynamic link, remember to select to redirect your users to the right app.
Click on the three dots in your dynamic link row and click on Link Details. Copy the extended link.
Open Integromat and select the last module you created (Webhook Response). Click on Show advanced settings and on the Header add :
Key Location - value the extended dynamic link that you copied.
If you want your app to elaborate data from the stripe OAuth response you can modify the extended dynamic link by adding ? on the link parameter: link=https://test.page.link?stripe_user_id={{14.stripe_user_id}}
And select the variable parsed from the JSON module. Remember to click on the save icon to save your scenario.
On Firebase Functions you can do this when the function stripe.oauth.token finish (I didn't test it):
res.setHeader('Location', your dynamic link);
res.status(301).send();
Remember to deploy it.
FLUTTER APP SETUP
The code here is very simple. To initialize the connect account registration you only need to set up a button that will launch the stripe connect URL. You can use launch(url);
You can find that URL here. Remember to be logged in to your stripe account to get the right stripe client id. You can easily get it in the same section you added the webhook link in your stripe connect settings.
Delete &redirect_uri=https://sub2.example.com on the URL.
Now you can test your app and will see that when you complete your stripe connect registration/login you will be redirected to your app.
If you want to have an in-app web view you can use this package
To handle the response, you need to have installed the package firebase_dynamic_links
Set your Main widget Stateful and on the initState run the method getDynamic() :
void getDynamic() {
FirebaseDynamicLinks.instance.getInitialLink().then((value) {
if (value != null) {
_connect(value);
}
});
FirebaseDynamicLinks.instance.onLink(onSuccess: (value) async {
if (value != null) {
_connect(value);
}
}, onError: (error) async {
debugPrint('DynamicLinks onError $error');
});
}
void _connect(value) {
Uri deepLink = value.link;
print("Link :" + deepLink.path);
print("Query :" + deepLink.queryParameters.toString());
String stripeUserId = deepLink.queryParameters["stripe_user_id"];
}
You need to have both of them to handle dynamic links when your app is running and when it's closed.

Zapier Rest Hook Subscription - How to get target options?

I am writing my first API integration with Zapier. I have created a trigger using a REST hook, and the trigger is firing correctly, but I am not sure how to determine what trigger option the user selected in Zapier. Specifically I allow them to choose a landing page, and unless I know WHICH landing page they want to activate the trigger I don't know how to handle it, but all I get back from Zapier on the subscription is this:
{
"subscription_url": "https://hooks.zapier.com/hooks/standard/102653/94703dc5c31247c4acb8b82977fd08dc/",
"target_url": "https://hooks.zapier.com/hooks/standard/102653/94703dc5c31247c4acb8b82977fd08dc/",
"event": "landing_page_submitted"
}
I know I am probably missing something. Should I expect to find the option selected in the trigger dropdown somewhere? Or do I need to configure something on the Zapier side to handle it?
David here, from the Zapier Platform team.
If I'm understanding you correctly, you just need to pass the data in from inputData.
In your hook subscription, there's a place to pass data (such as "event" above). You can add something like landing_page: bundle.inputData.landing_page. There's a more complete example here:
const subscribeHook = (z, bundle) => {
// bundle.targetUrl has the Hook URL this app should call when a recipe is created.
const data = {
url: bundle.targetUrl,
style: bundle.inputData.style
};
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: 'http://57b20fb546b57d1100a3c405.mockapi.io/api/hooks',
method: 'POST',
body: JSON.stringify(data)
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options)
.then((response) => JSON.parse(response.content));
};

Is there a way to get a users Bitmoji using Access tokens from Snapkit login web api?

I am attempting to use the snapkit login web api for a hybrid application. I have successfully been able to intercept the access token in the redirectURL. I was wondering if there was a way to get the users Bitmoji using this access_token and either the functions found in login.js or an http get call?
Api docs: https://docs.snapchat.com/docs/login-kit/#web
currently I have the access_token in a deeplinking function on my app.component.ts . I have attempted to push to a new page with the navController and passing in the access_token as a parameter, but this doesn't help when attempting to get the users information.
Thanks in advance for your help.
Here is the Deeplinking where I intercept the access_token using myapp://settings-set/ as the URL redirect and attempt to push a new page with the matching url.
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
this.deeplinks.routeWithNavController(this.nav,{
'/settings-set/:token': SettingsSetPage
}).subscribe((match) => {
// match.$route - the route we matched, which is the matched entry from the arguments to route()
// match.$args - the args passed in the link
// match.$link - the full link data
this.nav.push(SettingsSetPage, {
args: match
});
console.log('Successfully matched route', match.$args);
},
(nomatch) => {
// nomatch.$link - the full link data
console.error('Got a deeplink that didn\'t match', nomatch);
});
});
}
In the setting-set page I recieve the parameter using:
this.args = navParams.get('args');
console.log("this is args", JSON.stringify(this.args));
but don't know how to use the information to get the users information
The Bitmoji API can be very confusing at times. I suggest using Passport, a Node JS tool for OAuth, along with the Ionic framework. Snapchat has a guide that explains how to grab specific fields, such as user name and Bitmoji avatar, from a user's Snapchat profile using passport. You can follow this tutorial to learn how to integrate Node JS into your existing ionic app.
So in conclusion, try following these steps:
Integrate Node JS into your existing ionic app
Install Passport and follow Snapchat's guide for obtaining specific fields from the user's profile
Yes, like Mora said you can use passport which will make your life easier. We also have a sample passport app running here:
From the context you provided it seems like you have generated the code and not the access_token. After you get the code from the redirect url, you need to use the code to generate the access token. Check section 2.5 here.
Once you have the access token you can use that to request information. The crux of this lies in setting the "scope" correctly. To get the Bitmoji avatar make sure you set your scope to this at the very least:
var scope = ['https://auth.snapchat.com/oauth2/api/user.bitmoji.avatar'];
Hope this helps!

Azure App Service Facebook

I've migrated from Azure Mobile Service to an App Service but I'm having difficulty working out how best to implement extended Facebook auth.
In my old implementation I inherited from FacebookLoginProvider and fetched the token from the claims. I then added the CustomFacebookLoginProvider to my login providers. I then use the token to fetch more information about the user (their date of birth, friends and gender). With this information I created a user object and saved it to my DB.
Does anyone have any suggestions on how best to recreate this in App Service as I can't find any documentation.
As far as how to set up Facebook authentication, you can find documentation here (and it sounds like you've already figured out this much):
https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-how-to-configure-facebook-authentication/
Now that Facebook authentication is set up, you can refer to the following which shows how to obtain user information:
https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-dotnet-backend-how-to-use-server-sdk/#user-info
// Get the credentials for the logged-in user.
var credentials =
await this.User
.GetAppServiceIdentityAsync<FacebookCredentials>(this.Request);
if (credentials.Provider == "Facebook")
{
// Create a query string with the Facebook access token.
var fbRequestUrl = "https://graph.facebook.com/me?access_token="
+ credentials.AccessToken;
// Create an HttpClient request.
using (var client = new System.Net.Http.HttpClient())
{
// Request the current user info from Facebook.
using (var resp = await client.GetAsync(fbRequestUrl))
{
resp.EnsureSuccessStatusCode();
// Do something here with the Facebook user information.
var fbInfo = await resp.Content.ReadAsStringAsync();
}
}
}
Note that you must add a using statement for System.Security.Principal to make the GetAppServiceIdentityAsync extension method work.
For more information on which Facebook user properties you can query, see the Facebook documentation here: https://developers.facebook.com/docs/graph-api/reference/user. Note that you may need to specify which user properties you want as an additional fields query string parameter on your call to the Facebook graph.
The only change I had to make when switching from Mobile Service to Mobile App was to change the end of the callback URL in the developer portal to use /.auth/login/facebook/callback instead of /signin-facebook and it worked exactly the same way as before.
Note that this is for a Windows app with a .NET backend; you didn't specify what you're using so your mileage may vary.
I've been using the following approach to obtain the Facebook Access Token in the iOS app.
App Services includes the Facebook Access Token in the request header, refer to https://azure.microsoft.com/en-in/documentation/articles/app-service-api-authentication/.
To get to the access token, create a Custom API in the Azure Portal, e.g. facebookUserInfo, with the following code:
module.exports = {
"get": function (request, response, next) {
response.send(200, { facebookAccessToken: request.headers['x-ms-token-facebook-access-token'] });
}};
In the iOS app, use the following code to query the custom API:
let client = self.table!.client
if client.currentUser != nil {
client.invokeAPI("facebookUserInfo", body: nil, HTTPMethod: "GET", parameters: nil, headers: nil, completion: { (result, response, error) -> Void in
if let resultDict = result {
if let facebookAccessToken = resultDict["facebookAccessToken"]! {
print(facebookAccessToken)
}
}
}
}
By Using the Easy Auth feature of Azure App Services, I dont need to worry about authentication.
I have a blogpost on this. I have explained on how we can use the FB GraphApi's to query FB data. Here is the link: https://blogs.msdn.microsoft.com/kaushal/2017/06/08/using-easy-auth-to-query-facebook-information-via-graph-api/
I have the sample code deployed on Github. Here is the link: https://github.com/kaushalp/Facebook-GraphApi-with-EasyAuth

Redirect after user has logged in

I'm pretty new to Angular, and right now I'm just trying to get all my routes set up and working as I'd like.
Setup:
When a user navigates to certain pages (/settings for this example) the app should check if there is a user already logged in. If there is continue as usual. Otherwise the user should go to the login page (/login).
What I'd like:
After the user has successfully logged in they should go to the page they were originally trying to get to (/settings)
My question:
Is there an "Angular way" to remember where the user was trying to go to?
Relevant code:
app.js
.when('/settings', {
templateUrl: '/views/auth/settings.html',
controller: 'SettingsCtrl',
resolve: {
currentUser: function($q, $location, Auth) {
var deferred = $q.defer();
var noUser = function() {
//remember where the user was trying to go
$location.path("/login")
};
Auth.checkLogin(function() {
if (Auth.currentUser()) {
deferred.resolve(Auth.currentUser());
} else {
deferred.reject(noUser());
}
});
return deferred.promise;
}
}
})
login.js
$scope.submit = function() {
if(!$scope.logInForm.$invalid) {
Auth.login($scope.login, $scope.password, $scope.remember_me)
//go to the page the user was trying to get to
}
};
Much thanks to John Lindquist for the video which got me this far.
First off, you do not want to redirect the user to a login page.
An ideal flow in a single page web app is as follows:
A user visits a web site. The web site replies with the static assets for the
angular app at the specific route (e.g. /profile/edit).
The controller (for the given route) makes a call to an API using $http, $route, or other mechanism (e.g. to pre-fill the Edit Profile form with details from the logged in user's account via a GET to /api/v1/users/profile)
If/while the client receives a 401 from the API, show a modal to
login, and replay the API call.
The API call succeeds (in this case, the user can view a pre-filled Edit Profile form for their account.)
How can you do #3? The answer is $http Response Interceptors.
For purposes of global error handling, authentication or any kind of
synchronous or asynchronous preprocessing of received responses, it is
desirable to be able to intercept responses for http requests before
they are handed over to the application code that initiated these
requests. The response interceptors leverage the promise apis to
fulfil this need for both synchronous and asynchronous preprocessing.
http://docs.angularjs.org/api/ng.$http
Now that we know what the ideal user experience should be, how do we do it?
There is an example here: http://witoldsz.github.com/angular-http-auth/
The example is based on this article:
http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application
Good luck and happy Angularing!