How can Yahoo Mail be accessed by IMAP using OAuth or OAuth2 authentication - oauth

According to developer.yahoo.com/mail/ and IMAP responses:
* OK [CAPABILITY IMAP4rev1 ID MOVE NAMESPACE X-ID-ACLID UIDPLUS LITERAL+ CHILDREN XAPPLEPUSHSERVICE XYMHIGHESTMODSEQ AUTH=PLAIN AUTH=LOGIN AUTH=XOAUTH2 AUTH=XYMCOOKIE AUTH=XYMECOOKIE AUTH=XYMCOOKIEB64 AUTH=XYMPKI] IMAP4rev1 imapgate-1.8.1_01.20166 imap1009.mail.ne1.yahoo.com
Yahoo Mail can be accessed by IMAP using OAuth(2) authentication.
I registered my app on https://developer.yahoo.com/apps/ so I have got Client ID and Client Secret. I didn't find any scopes(API Permissions) related to Mail. Nevertheless I selected all API Permissions which were presented when I registered my app.
I tried to implement both OAuth and OAuth2.
OAuth2:
I cannot get the authorization code for scope "mail-r". When I generate URL(https://api.login.yahoo.com/oauth2/request_auth?client_id=CLIENT_ID&redirect_uri=oob&scope=mail-r&response_type=code) and open it in browser, the page with text "Developers: Please request scope from registered scopes and submit again." is displayed. It works for other scopes. For example, I'm able to get the authorization code for "sdct-r"
OAuth:
I'm able to get an access token. But when I send it with AUTHENTICATE XOAUTH2 command, I get "NO [AUTHENTICATIONFAILED] (#AUTH007) Bad scope" response.
So questions is what scope(s) should be set to access Yahoo Mail using IMAP and OAuth(2)?

Update February 27, 2017: This work-around will not work anymore as Yahoo has unfortunately taken down the cck-form.html page referenced below and does not seem to allow new apps to request mail related API access. Hopefully this changes.
Here is how you can create an App on yahoo with full access to emails. (recently yahoo remove this option from their UI) once proper permissions are in place, getting oauth tokens and accessing mail boxes should be straight forward and I am not covering it here.
Visit https://developer.yahoo.com/oauth/guide/cck-form.html and look for "Here is an example form along with sample values you can use in the form" and copy the example html into a local file and save it. A Copy of the html is available below.
Open the file on browser. fill appropriate info (set scope=ymrf for full mail access) and click on "pop window with debug".
Click on allow on the popup window. Sign in is required if you did not already login to yahoo on the browser.
go to https://developer.yahoo.com/apps/ and you should see your app with appropriate permissions.
<html>
<head>
<title>CCK Example</title>
</head>
<body>
<form target="yCredWindow" action="http://developer.apps.yahoo.com/projects/createconsumerkey" method="post" id="extAuthForm" name="extAuthForm">
<h2>Inputs</h2>
<p>* = Required</p>
<table>
<tr><th>Field</th>
<th>Input</th></tr>
<tr><td>* Application Name: </td>
<td><input name="name" id="name" value="Janrain Engage"></td></tr>
<tr><td>Description: </td>
<td><input name="description" id="desc"></td></tr>
<tr><td>appid: </td>
<td><input name="appid" id="appid"></td></tr>
<tr><td>Return to: </td>
<td><input name="return_to" id="return_to"></td></tr>
<tr><td>* Third Party Name: </td>
<td><input name="third_party" id="third_party" value="Janrain"></td></tr>
<tr><td>* Scopes: </td>
<td><input name="scopes" id="scope" value="ysrw"></td></tr>
<tr><td>Favicon URL: </td>
<td><input name="favicon" id="favicon"></td></tr>
<tr><td>Application URL: </td>
<td><input name="application_url" id="application_url"></td></tr>
<tr><td>* Domain: </td>
<td><input name="domain" id="domain" value="www.janrain.com"></td></tr></table>
<input type="hidden" name="debug" id="debug" value="true">
<button type="reset">clear all fields</button>
<button type="button" id="submitWithDebug">pop window with debug</button>
</form>
<h6>Note: A URL that starts with http:// is required for: Return to, Favicon URL and Application URL. However, you will get an error if you include http:// for the Domain.</h6>
<h2>Returns</h2>
<table>
<tr><td>Key returned:</td>
<td><input type="text" id="cKeyInputField"></td></tr>
<tr><td>Secret returned:</td>
<td><input type="text" id="cSecretInputField"></td></tr>
<tr><td>Appid returned:</td>
<td><input type="text" id="returnAppid"></td></tr></table>
<script src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"></script>
<script>
var formTarget = null;
// used by return_to.html to set the fields with the data that comes back
var setFields = function(id, val) { document.getElementById(id).value = val; };
// pops the window, then submits to it
var popWindowOnSubmit = function(e) {
window.open('', formTarget, 'status=0,toolbar=0,location=0,menubar=0,width=545,height=650');
document.extAuthForm.submit();
};
// handle submit when the button is clicked
YUI().use('node', function(Y) {
formObject = Y.one('#extAuthForm');
formTarget = formObject.getAttribute('target');
Y.on('click', popWindowOnSubmit, '#submitWithDebug');
});
</script>
</body>
</html>

As of august 2017, the only way to get the Email address is to use the scope called Profiles - Read/Write Public and Private. A very stupid choice of misleading options by Yahoo, since we don't want to "write" anything at all.
As a bonus headache, this will also return a list of all emails associated with the account, not just the main one. And there's no way to accurately identify which is the real one - the primary=true field returned in the list cannot be trusted.

You have to add the "Mail Read-Only" scope when you're creating/configuring the app on https://developer.yahoo.com/apps/.
Unfortunately, when I just tried to do that on a newly created app, the option wasn't available.
You may have to get in touch with Yahoo to have them allow you to request these scopes.

you have to add scope=openid while hitting authorization endpoint,
then after obtaining the token after hittng token endpoint,
hit profile endpoint with the obtained access token,
then we get emails under profile json object

In order for you to see the mail checkboxes in the list of potential scopes, Yahoo have to white-list your developer account. I could not find any documentation about this, or instructions for how to ask for it, so I can't back this up with any documentation.

I have found another way to create an app with the Mail API permissions enabled. I noticed if you include an 'api' parameter in the URL you can specify which scopes you want to include regardless of whether they are checked at the bottom. I noticed if you provided 'api=mail' in the URL it defaults to include Mail permissions. So to create a new app with Mail permissions use this URL:
https://developer.yahoo.com/apps/create/?api=mail

Related

Can I use Azure AD "businessPhones" in a URL parameter?

I am able to use a number of Azure AD profile entity fields in a URL parameter for parsing the logged in user's profile data into a form on our intranet for pre-fill or the like.
For example, ...URL?officelocation=(user.apiProfile.officeLocation)&fullname=(user.fullName)&email=(user.email)&jobtitle=(user.apiProfile.jobTitle).
All of these fields are single string data types according to https://graph.microsoft.com/v1.0/$metadata#users/$entity.
I'd like to know if it's possible to use the first or second value of a collection of strings as a parameter in the URL. And if so, how?
Take the "businessPhones" field for example. I've tried using &userphone=(user.businessPhones[0]) or other formations but am unable to return the field data.
On a page of our intranet which uses Azure AD as the Identity Provider via SAML 2.0 and uses the Microsoft Graph API, I am able to surface almost any user profile data dynamically on the page as content - including those fields which are in an array (or collection of strings), using the below script and html snippet as example.
<p>First name + Last name: <span id="user-firstname" style="font-weight:600;"></span> <span id="user-lastname" style="font-weight:600;"></span></p>
<p>Full name: <span id="user-fullname" style="font-weight:600;"></span></p>
<p>Email address: <span id="user-email" style="font-weight:600;"></span></p>
<p>Job title: <span id="user-jobtitle" style="font-weight:600;"></span></p>
<p>Office Phone: <span id="user-officephone" style="font-weight:600;"></span></p>
<p>Firm Name: <span id="user-firm" style="font-weight:600;"></span></p>
<p>Firm Address: <!--<span id="user-streetaddress" style="font-weight:600;"></span> <span id="user-city" style="font-weight:600;"></span>, <span id="user-postcode" style="font-weight:600;"></span>, --><span id="user-state" style="font-weight:600;"></span></p>
<p>UID: <span id="user-id" style="font-weight:600;"></span></p>
<p>Embedded Page: <span id="text-url" style="font-weight:600;"></span></p>
<script>
$('#user-firstname').html(CONNECTED_USER.firstName);
$('#user-lastname').html(CONNECTED_USER.lastName);
$('#user-fullname').html(CONNECTED_USER.fullName);
$('#user-email').html(CONNECTED_USER.email);
$('#user-jobtitle').html(CONNECTED_USER.apiProfile.jobTitle);
$('#user-officephone').html(CONNECTED_USER.apiProfile.phones[1].value);
$('#user-firm').html(CONNECTED_USER.apiProfile.officeLocation);
/*$('#user-streetaddress').html(CONNECTED_USER.apiProfile.streetAddress);*/
/*$('#user-city').html(CONNECTED_USER.apiProfile.city);*/
/*$('#user-postcode').html(CONNECTED_USER.apiProfile.postalCode);*/
$('#user-state').html(CONNECTED_USER.apiProfile.organizations[0].stateLocation);
$('#user-id').html(CONNECTED_USER.id);
$('#user-url').html(CONNECTED_USER.url);
$('#current-url').attr("href", window.location.href);
$('#text-url').html(window.location.href)
</script>
You can see that I use CONNECTED_USER.apiProfile.phones[1].value and CONNECTED_USER.apiProfile.organizations[0].stateLocation to return the data I wish to show.
Is it possible to do similar with URL parameters?
I think it's based on which language you used for composing the url. For example, in asp.net core, when you got the response from graph api, you can see that the BusinessPhones property is IEnumerable<string>, so you can't use user.businessPhones[0] but BusinessPhones.FirstOrDefault().
And if you compose the url in javascript, it should work when you use user.businessPhones[0], if it doesn't work, you may add console.log(user.businessPhones) to see the data.
By the way if some users has no value for businessPhones property, you may need to consider it.

Get Auth0 access token via command line

I am force to use an unergonomic web site (let’s call it zzz) that uses auth0 for authentication, and a REST API internally, and I have a strong desire to use the API directly.
Using the browser inspector, I can see how that API works, and if I use the JWT Access Token (transmitted using Authorization: Bearer) that I find there, I can script access to API.
The problem I am facing is getting such a JWT access token via auth0, given my username and password.
When I use the browser-based login, I see that zzz redirects me to
https://zzz.eu.auth0.com/login
?state=g6…mo
&client=uz…6j
&protocol=oauth2
&response_type=token%20id_token
&redirect_uri=https%3A%2F%2Ffoo.zzz.com%2Fcallback
&scope=openid%20read%3Amore%20scopes…
&audience=zz-api-prod
&nonce=0G…L7
&auth0Client=ey…n0%3D
(line breaks for your convenience)
I can now manually enter username and password, and get logged in, which seems to perform these steps:
A POST to
https://zzz.eu.auth0.com/usernamepassword/login
with a body of
{ "client_id":"uz…6j",
"redirect_uri":"https://foo.zzz.com/callback",
"tenant":"zzz",
"response_type":"token id_token"
"connection":"zzz-production-users",
"username":"…",
"password":"…",
"nonce":"0G…L7",
"state":"g6…mo",
"sso":true,
"_intstate":"deprecated",
"_csrf":"fb…KI",
"audience":"zzz-api-prod",
"auth0Client":"ey…n0=",
"scope":"openid read:stores more:scopes …",
"protocol":"oauth2"
}
and a response of
<form method="post" name="hiddenform" action="https://zzz.eu.auth0.com/login/callback">
<input type="hidden" name="wa" value="wsignin1.0">
<input type="hidden"
name="wresult"
value="ey…tE">
<input type="hidden" name="wctx" value="…">
<noscript>
<p>
Script is disabled. Click Submit to continue.
</p><input type="submit" value="Submit">
</noscript>
</form>
The JS on the login page seems to press that submit button, causing a POST to
https://zzz.eu.auth0.com/login/callback
which redirects to
https://foo.zzz.com/callback
#access_token=ey…7Q
&scope=openid%20read%3Amore%20scopes…
&expires_in=7200
&token_type=Bearer
&state=%7B%7D
&id_token=ey…Sg
… which contains the precious access token that I want.
Trying to script this precise flow, which would involve parsing the returned HTML to extract the wctx and wresult arguments, is quite tedious.
So my question is:
Is there a way to get the access_token some other way that is more convenient to script using just command line curl, or maybe some simple python code/library?
I have tried various things that I found on the auth0 documentation website (e.g. https://auth0.com/docs/api-auth/tutorials/password-grant#realm-support), but could not get them to work; presmably because they need to be explicitly enabled by zzz in their auth0 settings?
The correct approach should be a separation between these:
Unergonomic web site (Client A) - which uses the implicit flow
Web API
Client B (your command line) - which uses a different flow
In Auth0 you should configure a new OAuth Client Entry for Client B, which should probably use a different flow - perhaps the password grant you mention.
You will at least be able to get a token in this manner. Whether the API accepts calls from you may depend on other design aspects.

Quickbooks Online - How to implement SSO with intuit in Ruby/Rails

I was able to connect with to Intuit using the Minimul/QboApi gem and get the "Connect to Quickbooks" button working with oauth2 based on the example provided on Github. However neither the gem nor the samples show how to implement single sign on with Intuit. In the example provided by Minimul, the Connect To Quickbooks button is produced by intuit's javascript found at https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere-1.3.5.js
and a setup script and the tag . The tag appears to have been deprecated. Or at least, it doesn't appear to do anything other than produce the button with the right text and logo on it.
But bottom line, I have been unable to find any documentation on the ipp.anywhere.js package, and not even sure if i's meant to used with oauth2 since it's not mentioned anywhere. I believe that the connect to intuit button does the right things, but the guidelines seem pretty strict about what that the button needs to say the right thing and have th eright logo or they will reject it in the store. They also seem to suggest that users are much more likely to try something if an SSO with Intuit workflow is enabled. Any help appreciated.
After some further work, I figured out a solution that can create a 'log in with Inuit button' , although it's a bit of a javascript hack. First, I determined that the only thing I really needed to change was the button image. In other respects the code behind ` works fine for either a "login with intuit" or "connect to intuit work flow" . The only problem is the button image.
Here is the code (adapted from Minimul/QboApi) to get access and oauth2 refresh tokens via a "Connect to Quickbooks" button.
Setup in the controller code in login or sessions controller:
def new
#app_center = QboApi::APP_CENTER_BASE # "https://appcenter.intuit.com"
state= SecureRandom.uuid.to_s
intuit_id = ENV["CLIENT_ID"]
intuit_secret = ENV["CLIENT_SECRET"]
client = Rack::OAuth2::Client.new(
identifier: intuit_id,
secret: intuit_secret,
redirect_uri: ENV["OAUTH_REDIRECT_URL"],
uthorization_endpoint:"https://appcenter.intuit.com/connect/oauth2",
token_endpoint: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer",
response_type: "code"
)
#make sure to include at least "openid profile email"
#in the scope to you can retrieve user info.
#uri = client.authorization_uri(scope: 'com.intuit.quickbooks.accounting openid profile email phone address', state: state)
end
Here is the code required to generate the button on the view. (The view needs to load jquery as well in order for the script to work.)
<script type="text/javascript" src="<%= #app_center %>/Content/IA/intuit.ipp.anywhere-1.3.5.js">
</script>
<script>
intuit.ipp.anywhere.setup({
grantUrl: "<%== #uri %>",
datasources: {
quickbooks: true,
payments: false
}
});
</script>
<div>
<ipp:connecttointuit></ipp:connecttointuit>
This code produces the following html on the page delivered to the client:
<ipp:connecttointuit>
Connect with QuickBooks
</ipp:connecttointuit>
This code produces a button with the Connect with QuickBooks image, and an event handler inside intuit.ipp.anywhere-1.3.5.js attaches itself to the click event.
The problem is that the button is styled by the class=intuitPlatformConnectButton attribute inside the generated <a> tag, so if you want a "login with intuit button instead of a connect with intuit button the class on the anchor needs to be changed to class='intuitPlatformLoginButtonHorizontal' but still needs to attach to the event handler defined for <ipp:connecttointuit>. The best solution that doesn't require mucking with intuit.ipp.anywhere is to create the connect button and hide it, and then create another tag styled with class=intuitPlatformLoginButtonHorizontal whose click event calls click on the hidden connect button. I use AngularJs on my login page, so I handle the click with ng-click, but it could be done simply with jquery alone.
new.html.erb:
<div>
</div>
<div>
<ipp:connecttointuit id="connectToIntuit" ng-hide="true">< </ipp:connecttointuit>
</div>
and the controller code:
$scope.intuit_login = function() {
let el = angular.element("#connectToIntuit:first-child")
el[0].firstChild.click();
}
This will result in a redirect upon authentication to the supplied redirect url, where you can use openid to get the user credentials.

How to use NSUserDefaults in phonegap?

I am new to this iOS/phonegap technology.
I am working on an iPhone/iOS app using phonegap. It has a login page with two text fields "Username" & "Password".
<input type="text" class="form-control input-lg user_name" id="txtUserName" placeholder="Username" />
<input type="password" class="form-control input-lg pass_word" id="txtPassword" placeholder="Password" />
<button id="btnLogin" class="large color blue button login_top btn-block" type="submit" value="Login">Login</button>
On $(document).ready(function() Login processing is carried out.
Now I want to save email address of the user. i.e When I logged out it should remember the email address so it doesn't have to be input again.
I am developing this using phonegap. I went through many links and found out that this can be done using
1. NSUserDefaults
2. KeyChain
I am thinking of using NSUserDefaults, but am not understanding how to implement this thing.
i.e Since this is native c code we have to write in the appDelegate.m file. Am I right?
And then how to link this code to my login page?
Can anyone please send me the full code to implement this functionality.
I mean the code that i need to add in appdelegate and linking that code to my login page.
If you or someone else needs it,
There is a cordova plugin for that:
https://github.com/apla/me.apla.cordova.app-preferences/
cordova plugin add me.apla.cordova.app-preferences
Example from it's site:
var prefs = plugins.appPreferences;
// store key => value pair
prefs.store (ok, fail, 'key', 'value');
// store key => value pair in dict (see notes)
prefs.store (ok, fail, 'dict', 'key', 'value');
// fetch value by key (value will be delivered through "ok" callback)
prefs.fetch (ok, fail, 'key');
// fetch value by key from dict (see notes)
prefs.fetch (ok, fail, 'dict', 'key');

Twitter Timeline through Expression Engine

Can anyone help me integrate Twitter through Expression Engine. I am new to expression engine and I have tried to follow the example the Twitter Timeline developed by the EE team but couldn't get it working.
Can anyone help me with step by step process in EE2?
Thanks
Using the example from the Twitter Timeline Plugin download page, insert the following code into one of your ExpressionEngine templates:
{exp:twitter_timeline screen_name="ladygaga" limit="3"}
<div class="tweet">
<div class="date">{created_at format="%m-%d %g:%i"}</div>
<div class="author">
<div class="icon">
<img src="{profile_image_url}" width="48" height="48" alt="" />
</div>
{name}
</div>
<div class="status">{text}</div>
</div>
{/exp:twitter_timeline}
Note: The plugin only works on public Twitter feeds, so make sure that the feed your trying to display is not private. For this example, I'm using Lady Gaga's twitter stream.
All error messages are logged in the Template Parsing Log.
Therefore if you have no output, or unexpected output, enable the Template Parsing Log in the Control Panel's Output and Debugging Preferences at: CP Home > Admin > System Administration > Output and Debugging.
Reload the page in your browser and look through the Template Parsing Log for information from the Twitter Timeline:
If you still can't get the Twitter Timeline plugin to work, post a description of your problem to the ExpressionEngine 2 Technical Support Forum — they'll be able to better help troubleshoot your issue.

Resources