Getting transactions from WebView with testing credentials (Plaid) - android

How can I get transactions from WebView with testing credentials on Android?
This is my code:
public class PlaidViewActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plaid_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Initialize Link
HashMap<String, String> linkInitializeOptions = new HashMap<String,String>();
linkInitializeOptions.put("key", "56632c5b63db7b7a155000b7c9507649");
linkInitializeOptions.put("product", "transact`enter code here`ions,auth");
linkInitializeOptions.put("apiVersion", "v2"); // set this to "v1" if using the legacy Plaid API
linkInitializeOptions.put("env", "sandbox");
linkInitializeOptions.put("clientName", "Test App");
linkInitializeOptions.put("selectAccount", "true");
linkInitializeOptions.put("webhook", "http://requestb.in");
linkInitializeOptions.put("baseUrl", "https://cdn.plaid.com/link/v2/stable/link.html");
// If initializing Link in PATCH / update mode, also provide the public_token
// linkInitializeOptions.put("public_token", "PUBLIC_TOKEN")
// Generate the Link initialization URL based off of the configuration options.
final Uri linkInitializationUrl = generateLinkInitializationUrl(linkInitializeOptions);
// Modify Webview settings - all of these settings may not be applicable
// or necesscary for your integration.
final WebView plaidLinkWebview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = plaidLinkWebview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
WebView.setWebContentsDebuggingEnabled(true);
// Initialize Link by loading the Link initiaization URL in the Webview
plaidLinkWebview.loadUrl(linkInitializationUrl.toString());
// Override the Webview's handler for redirects
// Link communicates success and failure (analogous to the web's onSuccess and onExit
// callbacks) via redirects.
plaidLinkWebview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Parse the URL to determine if it's a special Plaid Link redirect or a request
// for a standard URL (typically a forgotten password or account not setup link).
// Handle Plaid Link redirects and open traditional pages directly in the user's
// preferred browser.
Uri parsedUri = Uri.parse(url);
if (parsedUri.getScheme().equals("plaidlink")) {
String action = parsedUri.getHost();
HashMap<String, String> linkData = parseLinkUriData(parsedUri);
if (action.equals("connected")) {
// User successfully linked
Log.d("-->Public token: ", linkData.get("public_token")+"");
Log.d("-->Account ID: ", linkData.get("account_id")+"");
Log.d("-->Account name: ", linkData.get("account_name")+"");
Log.d("-->Institution type: ", linkData.get("institution_type")+"");
Log.d("-->Institution name: ", linkData.get("institution_name")+"");
// Reload Link in the Webview
// You will likely want to transition the view at this point.
plaidLinkWebview.loadUrl(linkInitializationUrl.toString());
} else if (action.equals("exit")) {
// User exited
// linkData may contain information about the user's status in the Link flow,
// the institution selected, information about any error encountered,
// and relevant API request IDs.
Log.d("User status in flow: ", linkData.get("status"));
// The requet ID keys may or may not exist depending on when the user exited
// the Link flow.
Log.d("Link request ID: ", linkData.get("link_request_id"));
Log.d("API request ID: ", linkData.get("plaid_api_request_id"));
// Reload Link in the Webview
// You will likely want to transition the view at this point.
plaidLinkWebview.loadUrl(linkInitializationUrl.toString());
} else {
Log.d("Link action detected: ", action);
}
// Override URL loading
return true;
} else if (parsedUri.getScheme().equals("https") ||
parsedUri.getScheme().equals("http")) {
// Open in browser - this is most typically for 'account locked' or
// 'forgotten password' redirects
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
// Override URL loading
return true;
} else {
// Unknown case - do not override URL loading
return false;
}
}
});
}
// Generate a Link initialization URL based on a set of configuration options
public Uri generateLinkInitializationUrl(HashMap<String,String>linkOptions) {
Uri.Builder builder = Uri.parse(linkOptions.get("baseUrl"))
.buildUpon()
.appendQueryParameter("isWebview", "true")
.appendQueryParameter("isMobile", "true");
for (String key : linkOptions.keySet()) {
if (!key.equals("baseUrl")) {
builder.appendQueryParameter(key, linkOptions.get(key));
}
}
return builder.build();
}
// Parse a Link redirect URL querystring into a HashMap for easy manipulation and access
public HashMap<String,String> parseLinkUriData(Uri linkUri) {
HashMap<String,String> linkData = new HashMap<String,String>();
for(String key : linkUri.getQueryParameterNames()) {
linkData.put(key, linkUri.getQueryParameter(key));
}
return linkData;
}
This is my code and I am getting the result in success
05-09 10:29:32.268 3091-3091/? D/-->Public token:: public-sandbox-2fddfc55-abb1-439d-84e0-6b1207503eb3
05-09 10:29:32.268 3091-3091/? D/-->Account ID:: nordpMwPjZSoVok6XzaeCQArXDjjM4H6Nj3ox
05-09 10:29:32.268 3091-3091/? D/-->Account name:: Plaid Credit Card
05-09 10:29:32.269 3091-3091/? D/-->Institution type:: null
05-09 10:29:32.269 3091-3091/? D/-->Institution name:: Citi
from this, I want to get transaction please help me out
Using postman i did
https://sandbox.plaid.com/transactions/get
{
"client_id": "5ae9627a6c0fcd0012c97bf1",
"secret": "b67ff6d1a462303cf43e2e83edaf33",
"access_token": "public-sandbox-2fddfc55-abb1-439d-84e0-6b1207503eb3",
"start_date": "2017-01-01",
"end_date": "2017-02-01",
"options": {
"count": 250,
"offset": 100
}
}
but i am getting an error response
{
"display_message": null,
"error_code": "INVALID_ACCESS_TOKEN",
"error_message": "provided token is the wrong type. expected \"access\", got \"public\"",
"error_type": "INVALID_INPUT",
"request_id": "bTgTg"
}
like this please help out

Old question, yet still writing this for the records
It looks like you were using public token as stated in your Postman request. You need to exchange the public token with an access token first, which would eliminate the need for direct communication between end user and plaid.
"access_token": "public-sandbox-2fddfc55-abb1-439d-84e0-6b1207503eb3",
For the reference, Plaid access tokens start with access-.. not public-..
For more information you can refer there.
https://plaid.com/docs/quickstart/#rotate-access-token

Related

How to get Instagram Following List using Instagram graph api

How to get the following list from the Instagram account using the access token
I tried everything but not work.
here some API link which I tried before but none of them work.
I tried this one https://www.instagram.com/urvish_._/?__a=1
also this one
I tried but nothing can help me.
You can get the following (or also follower) list using the code below. Steps:
Make sure you're logged in on instagram.com
Open the API link: https://www.instagram.com/urvish_._/?__a=1 (your target username here is urvish_._)
Open the browser console: normally Ctrl+Shift+J on Windows/Linux or ⌘+Option+J on Mac
Paste this code and press Enter:
const GRAPHQL_MAX_PER_PAGE = 50;
async function getList() {
let pageLimit = 200; // from my testing
let baseInfo = JSON.parse(document.getElementsByTagName('body')[0].innerText);
let userId = baseInfo.graphql.user.id;
let config = { user_edge: 'edge_follow', query_hash: 'd04b0a864b4b54837c0d870b0e77e076', total_count: baseInfo.graphql.user.edge_follow.count };
// for followers instead of followings:
// { user_edge: 'edge_followed_by', query_hash: 'c76146de99bb02f6415203be841dd25a', total_count: baseInfo.graphql.user.edge_followed_by.count }
let after = null, hasNext = true, thisList = [];
for (pageCount = 1; hasNext && (pageCount <= pageLimit); ++pageCount) {
try {
let response = await fetch(`https://www.instagram.com/graphql/query/?query_hash=${config.query_hash}&variables=` + encodeURIComponent(JSON.stringify({
id: userId, include_reel: true, fetch_mutual: true, first: GRAPHQL_MAX_PER_PAGE, after: after
})));
if (!response.ok) {
console.warn(`Failed at page number ${pageCount.toLocaleString()}. HTTP status ${response.status}: ${response.statusText}.`);
break;
}
try {
response = await response.json();
} catch (error) {
console.error(`You may need to verify your account. Stopping. Failed at page number ${pageCount.toLocaleString()}.`, error);
break;
}
hasNext = response.data.user[config.user_edge].page_info.has_next_page
after = response.data.user[config.user_edge].page_info.end_cursor
thisList = thisList.concat(response.data.user[config.user_edge].edges.map(({ node }) => {
return {
id: node.id,
username: node.username,
full_name: node.full_name,
profile_pic_url: node.profile_pic_url,
};
}));
} catch (error) {
console.warn(`Error at page number ${pageCount.toLocaleString()}:`, error);
}
console.log(`${thisList.length.toLocaleString()} of ${config.total_count.toLocaleString()} fetched so far`);
}
console.info(`${thisList.length.toLocaleString()} fetched.`);
console.log(thisList);
}
getList()
Browser console showing a fetched list after code execution
In the code I've set the page limit to 200 so you can get up to 10,000 of your followings.
PS: For a way to visualise your lists and get more details, you can try Instagram Lists, a tool I made.

Google Login/Signin on Yandex Android extension

I'm trying to run my desktop chrome extension on Android, so i tried running it in Yandex browser on my phone. It runs ok except for the google login.(everything works well on desktop Chrome and desktop Yandex).
This code is called by the background scripts:
var url = 'https://accounts.google.com/o/oauth2/auth' +
'?client_id=' + clientId +
'&response_type=id_token' +
'&access_type=offline' +
'&redirect_uri=' + redirectUri +
'&scope=' + scopes;
getIdToken: function (message) {
const _this = this;
var idToken = "";
chrome.identity.launchWebAuthFlow(
{
'url': url,
'interactive': true
},
function (redirectedTo) {
console.log("[2]auth-manager called: "+redirectedTo);
if (chrome.runtime.lastError) {
// Example: Authorization page could not be loaded.
console.log("lastError: "+chrome.runtime.lastError.message);
}
else {
var response = redirectedTo.split('#', 2)[1];
// Example: id_token=<YOUR_BELOVED_ID_TOKEN>&authuser=0&hd=<SOME.DOMAIN.PL>&session_state=<SESSION_SATE>&prompt=<PROMPT>
idToken = (response.split('&')[0]).split('=', 2)[1];
console.log("auth-manager id token", idToken);
if (message != undefined) {
message.data.google_id_token = idToken;
cloudWebSocket.sendMessage(JSON.stringify(message));
_this.isLogged = true;
closePopup();
alert('login successful');
}
}
}
);
}
When I call this function, redirectedTo is undefined, and i get a chrome.runtime.lastError.message:"canceled". That's it.
I use the very same manifest from the desktop apps, with the same clientId,redirectUri and scopes.
I can't figure out, what causes this problem?
If there's another way to perform a google login without this issue it can also help.
see the Web Extensions API ...in particular the platform support table there.
initiating the oAuth2 flow on the server-side should nevertheless be possible.

MVC 4 Web API 2 ajax call all parameters optional

I realy want your option.
We update a .net MVC 3 project to MVC 4 with web api 2, this a web service.
The ajax calls is from android machines with the Devextreme/Phonegap.
After the update the web service when i call login from android i get
"No HTTP resource was found that matches the request URI 'http://www.whatever.gr/MVCService/Actions/Login'"
I want to set the route so that all methods of the MVC service can have parameters optional.
I can't get this work..
We can't change the source on the android app,and ajax call is the code below
function doLogin(username, password, callback) {
loading(true);
var dataStr = "uid=" + uid + "&username=" + username + "&password=" + password;
var success = false;
var token = "";
$.ajax({
type: "POST",
url: registrationServiceUrl + 'Login',
data: dataStr,
beforeSend: function () {
//alert("registration no: " + registrationid);
},
success: function (retval) {
if (retval.indexOf('SUCCESS') == 0) {
success = true;
token = retval.substring(8);
//setTokenToSettings(token);
} else {
success = false;
};
callback(success, token);
loading(false);
},
error: function (retval) {
callback(success, token);
loading(false);
}
});
}
The route in MVC is
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
When i hit like below with parameters in a browser i have a response
'http://www.whatever.gr/MVCService/Actions/Login?param1=1&param=2&param3=3'.
I want to have the behavior, when to hit 'http://www.whatever.gr/MVCService/Actions/Login'
or
'http://www.whatever.gr/MVCService/Actions/Login?param1=1&param=2&param3=3&invalidParamName=x'.
And the web service method to be trigger with empty parameters values.
But without setting optional parameters in the method
public string Login(string pamar1 = "",string param2 = "", string param3 = "")
With MVC 3 this was working fine as I explained before.
Thanks in advance and for your time.
In Web API, it's very simple to remember how parameter binding is happening.
if you POST simple types, Web API tries to bind it from the URL
if you POST complex type, Web API tries to bind it from the body of
the request (this uses a media-type formatter).
This asp.net page explains it all.
http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

Google URL shorten decode android

I have a shorten url done by http://goo.gl/
I need to get the original url. Is there any api to do that in ANDROID.
What I tried for make shorter -
compile 'com.andreabaccega:googlshortenerlib:1.0.0'
GoogleShortenerPerformer shortener = new GoogleShortenerPerformer(new OkHttpClient());
String longUrl = "http://www.andreabaccega.com/";
GooglShortenerResult result = shortener.shortenUrl(
new GooglShortenerRequestBuilder()
.buildRequest(longUrl)
);
if ( Status.SUCCESS.equals(result.getStatus()) ) {
// all ok result.getShortenedUrl() contains the shortened url!
} else if ( Status.IO_EXCEPTION.equals(result.getStatus()) ) {
// connectivity error. result.getException() returns the thrown exception while performing
// the request to google servers!
} else {
// Status.RESPONSE_ERROR
// this happens if google replies with an unexpected response or if there are some other issues processing
// the result.
// result.getException() contains a GooglShortenerException containing a message that can help resolve the issue!
}
Load the ShortURL with a HttpURLConnection, then you can read out the target URL with
httpURLConnection.getHeaderField("location");
Full solution
URL url = new URL("http://goo.gl/6s8SSy");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
Log.v("Full URL", httpURLConnection.getHeaderField("location"));
Can't test live right now, but this should be working.
I made my solution. What I did -
I open a webview without visibility then call that url.Then on page load complete I a fetching the url
WebView webView;
webView = (WebView)findViewById(R.id.help_webview);
webview.loadUrl("http://goo.gl/tDn72f");
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
String myResult = webView.getUrl();
}
});

Zend framework 2 + Android Mobile + ZfcUser Authentication

I need to authenticate via Android on my website (Zend Framework2+ZfcUser+ZfcUserDoctrineORM).
I want to call an url that authenticate me and return a json object that contains my session_id.
I don't know if it is the correct way but whatever i don't know how to do that with zfcUser.
David
Next, i will be able to store this session_id into Shared Preferences storage.
First of all sorry for my English.
In my application i need almost the same.
Ok. So in yoursite.com/module/YourModuleName/Module.php do:
use YourModuleName\Model\YourModuleName;
use YourModuleName\Model\YourModuleName;
class Module {
public function onBootstrap(MvcEvent $e) {
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$auth = $sm->get('zfcuser_auth_service');
$model = new OrdersManager();
if (!$auth->hasIdentity()) {
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($app, $sm, $auth, $model) {
$match = $e->getRouteMatch();
// No route, this is a 404
if (!$match instanceof RouteMatch) {
return;
}
$match = $e->getRouteMatch();
$matchParams = $match->getParams();
// $matchParams['hash'] == some url param
if (isset($matchParams['hash'])) {
$model->setDbAdapterColibo($sm->get('dbAdapter'));
$usersSqlObject = $model->getUsers();
$salt = md5('caw');
foreach ($usersSqlObject as $key => $user) {
$hash = hash('sha256', $salt.$param1.$user['user_id']);
if ($hash == $matchParams['hash']) {
$authAdapter = $sm->get('ZfcUser\Authentication\Adapter\AdapterChain');
$request = $app->getRequest();
$request->getPost()->set('identity', $user['email']);
// You may use user password to auth user
$request->getPost()->set('credential', $user['user_id']);
$result = $authAdapter->prepareForAuthentication($request);
$auth->authenticate($authAdapter);
// do your staff with session or other.
// after this you will be redirect to page from where query was
break;
}
}
}
});
}
}
}
Don`t forget about yoursite.com/module/YourModuleName/config/module.config.php
You need to add route with your URL param, to receive it in $matchParams = $match->getParams();
In case I have describe you will be auth and immediately redirect to the site.
Example:
http://example.com/someController/someAction/param1/param2/hash...
the result will be auth and open page http://example.com/someController/someAction/param1/param2/hash...
Ok. This is what i need for my app. Hope this help.
P.S. Some ideas get from Zend Framework 2 - Global check for authentication with ZFCUser

Categories

Resources