Validate Gmail account and retrieve basic profile info - gmail-api

Is there a way to validate account existence and retrieve basic gmail account info such as name and photo url using only email ?
Previously it was possible to get account photoUrl using the following endpoint:
http://picasaweb.google.com/data/entry/api/user/<hereYourUserIdOrYourEmail>?alt=json
but it was shut down.

You can't access that information with the gmail-api. If you are the admin of a g suite domain, you could use the directory API to obtain that info.
If the application is not intended for a specific domain, you can implement google oauth2 with JavaScript in the front-end, the user would have to authenticate and this way you'll be able to access the basic information. You need to create a project in cloud.google.com and get credentials (a clientID is needed in the code). More explanation here:
https://developers.google.com/identity/sign-in/web/sign-in
Implementation example (only clientID missing):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="google-signin-client_id" content="#clientId">
<title>Oauth2 web</title>
<!-- Google library -->
<script src="https://apis.google.com/js/platform.js" async defer></script>
<!-- Jquery library to print the information easier -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<!-- Bootstrap library for the button style-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div id="profileinfo">
</div>
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
$("#profileinfo").append("<h2>Sup " + profile.getName() + ", welcome home my friend</h2>");
$("#profileinfo").append("<img style='width:250px;height:250px' src='" + profile.getImageUrl() + "'><br><br>");
$("#profileinfo").append("<p>Your email is: " + profile.getEmail() + "</p>");
}
</script>
<button type="button" class="btn btn-danger" onclick="signOut();">Sign out</button>
<script>
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
$("#profileinfo").empty();
$("#profileinfo").append("<h2>Goodbye old friend</h2>");
});
}
</script>
</body>
</html>

Related

Refresh token in Gmail API?

After successful login, I am getting access token, expire token type, and this stuff in my console by "console.log("my response ",response)". But there is no refresh token. how to get a refresh token.
And 2nd question is, How to get an access token using a refresh token?
I am using JavaScript.
And guide me is this a best way way to get an access token?
Successful login is not giving refresh token, without refresh token how can I refresh my access token?
Here is my code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>FIFV Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<link rel="stylesheet" href="home.css">
<script src="https://apis.google.com/js/api.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.9.1/font/bootstrap-icons.css">
</head>
<body>
<div class="wrapper fadeInDown">
<div id="formContent">
<!-- Tabs Titles -->
<!-- Icon -->
<div class="fadeIn first">
<img src="Images/company Logo.png" id="icon" alt="User Icon" />
</div>
<!-- Login Form -->
<form>
<h3 class="heading"> Welcome to
FIFV authentication </h3>
<p class="shortPara">Please authenticate yourself to get access to the dashboard.</p>
<!-- <input type="submit" class="fadeIn fourth" value="Log In" href="Home.html"> -->
<br>
<button onclick="authenticate().then(loadClient)" type="button" class="btn"><a>Authorise</a></button>
<p id="errorMsg"></p>
</form>
</div>
</div>
<script>
/**
* Sample JavaScript code for gmail.users.messages.list
* See instructions for running APIs Explorer code samples locally:
* https://developers.google.com/explorer-help/code-samples#javascript
*/
// Authentication code
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({ scope: "https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.compose https://www.googleapis.com/auth/gmail.readonly" })
.then(function (response) { console.log("Sign-in successful", response);
console.log("Access Token", response.Bc.access_token)
localStorage.setItem("accessToken", response.Bc.access_token)
localStorage.setItem("expire", response.Bc.expires_in)
},
function (err) { console.error("Error signing in", err); });
}
function loadClient() {
gapi.client.setApiKey("my-api-key");
return gapi.client.load("https://gmail.googleapis.com/$discovery/rest?version=v1")
.then(function () { console.log("GAPI client loaded for API"); },
function (err) { console.error("Error loading GAPI client for API", err);
document.getElementById('errorMsg').innerHTML = err;
});
}
gapi.load("client:auth2", function () {
gapi.auth2.init({
client_id: "my-client-id",
plugin_name: "hello"
});
});
function logout() {
fetch("https://oauth2.googleapis.com/revoke?token=" + token,
{
method: 'POST',
headers: {
"Content-type": "application/x-www-form-urlencoded"
}
})
.then((data) => {
location.href = "http://localhost:5500/index.html"
})
}
</script>
<script src="home.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.11.6/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</body>
</html>
I was reviewing the Google Documentation for JavaScript, and I found the following sample that might help you:
if (gapi.client.getToken() === null) {
// Prompt the user to select a Google Account and ask for consent to share their data
// when establishing a new session.
tokenClient.requestAccessToken({prompt: 'consent'});
} else {
// Skip display of account chooser and consent dialog for an existing session.
tokenClient.requestAccessToken({prompt: ''});
}
}
You can read more information about this here, and information about the refresh token can be found here.
Lastly, you can read the information in this question. It has a lot of information about the refresh token.

How to get userid in angular view from Spring Boot REST Controller

In my application, I am using Spring Security for authentication using database. Part of redirection strategy is to if user is ADMIN, redirect user to ADMIN(HOME) page, if user is USER, redirect that user to USER page.
When a user with role USER logs in, he sees USER page which is like below:
<html ng-app="benefitApp">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Benefit Application</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="/css/bootstrap.css" />
<script src="https://code.angularjs.org/1.6.1/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular-resource.js"></script>
<script type="text/javascript" src="./js/app.js"></script>
</head>
<body ng-controller="UserCtrl">
<p>Hello <p th:text="${name}"></p></p>
<div>
<ul class="menu">
<li><a href='userProfile({{userid}})'>userprofile</a></li>
</ul>
<div ng-view="ng-view"></div>
</div>
</body>
</html>
I am trying to pass logged in user's id to this page from REST controller like this :
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String userpage(Model model) {
LOGGER.info(" Enter >> userpage() ");
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
String name = auth.getName();
User user = userManager.findUserByEmail(name);
model.addAttribute("name", name);
model.addAttribute("userid", user.getId());
return "user";
}
But I am not getting any userid in user.html page. What am I missing here?
You are using angularjs data-binding expression to bind userid to function:
<li><a href='userProfile({{userid}})'>userprofile</a></li>
which is wrong way.
Since you are using Thymeleaf, I would suggest you to use expression like this to bind link for user profile : th:href="#{${link}}"
# prefix is used to specify a link and $ prefix is used to bind your model value and then create a link with th:href like this:
<li><a th:href="#{'#/user/profile/' + ${userid}}">userprofile</a></li>
Or you can initialize a variable with ng-init like this:
<div ng-init="userId = ${userid}"></div>
And use it like this:
<li><a ng-href="#/user/profile/{{userId}}">userprofile</a></li>

how to send csv file to download using NodeJS and AngularJS [duplicate]

I need to provide a link to download a file, the link must be hidden and accessible by any users, Here is my code , there are no errors whatsoever, but I can't even get the download dialog box to open:
Template
<a ng-href="#" target="page" type="button" class="btn"
ng-click="download()">Download</a>
Script file
$scope.download = function(){
//here i need to know the code,can anybody explain me
}
I had to achieve the functionality. Also had to make sure that it works for all the major supported browsers.
Here's the solution for the same!!!
Happy Coding!!!
Your View/HTML
<a target="_self" class="ui right floated btn btn-warning" href ng-click="downloadInvoice()"> Download </a>
Your Controller
$scope.downloadInvoice = function () {
$http.post(url,requestData, {responseType:'arraybuffer',headers:header
})
.success(function (response) {
var file = new Blob([response], {type: 'application/pdf'});
var isChrome = !!window.chrome && !!window.chrome.webstore;
var isIE = /*#cc_on!#*/false || !!document.documentMode;
var isEdge = !isIE && !!window.StyleMedia;
if (isChrome){
var url = window.URL || window.webkitURL;
var downloadLink = angular.element('<a></a>');
downloadLink.attr('href',url.createObjectURL(file));
downloadLink.attr('target','_self');
downloadLink.attr('download', 'invoice.pdf');
downloadLink[0].click();
}
else if(isEdge || isIE){
window.navigator.msSaveOrOpenBlob(file,'invoice.pdf');
}
else {
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
})
};
First of all, your can't "hide/not public" a link in a web based technology (HTML/CSS/JavaScript) application. Downloads are handled by the client, so the Download/Link-URL must be public. You can try to "hide" protective params like e.g. IDs in the download URL by using a backend executed programming language like "PHP or node.js, etc.". In that way you can create hash URLs like http://www.myside.com/download/359FTBW!S3T387IHS to hide parameters like the recordId in your URL.
By knowing this, your solution is pretty easy. Just use the HTML attribute download like <a href="http://mydownloadurl" download>link text</a> to force the browser to download the href source. No ng-click is needed here. Unfortunately the download attribute is not supported by Safari browser. This doesn't realy matter while the browser is handling the download itself. Depending on the users system OS configuration the file will be downloaded or directly opened in a programm installed on that system. For example, a PDF file will be opened in a PDF Viewer if some pdf viewer application is available.
I wrote a Plunker which handles ng-href in a AngularJS controller $scope. I hope this is what you need.
Your controller:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.fileHref = 'http://www.analysis.im/uploads/seminar/pdf-sample.pdf';
});
Your view:
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<a ng-href="fileHref" download="yourFilename">Download</a>
</body>
</html>

Authentication with loopback and angular

I am attempting to perform authentication with loopbackJS as a backend provider. After following the documentation on loopback's doc site I'm still receiving an "Unknown Provider error".
Here is the following code I've written so far.
Home View
<form class="centered" ng-controller="UserController as user">
<div class ="form-group">
<label for="exampleEmail">Email</label>
<input class="form-control" type="text" name="email" placeholder="{{user.usernames.email}}">
<label for="examplePassword">Password</label>
<input class="form-control" type="password" name="password" placeholder="{{user.usernames.password}}">
<p>{{user.description}}</p>
<button class="button" ng-show="user.usernames.signin" ng-submit="login()">login</a> </button>
</div>
</form>
Auth Controller
var app = angular.module('app')
app.controller('UserController', ['$scope','AuthService', '$state', function($scope, AuthService, $state){
$scope.user = {
email: 'foo#bar.com',
password: 'foobar'
};
$scope.login = function() {
AuthService.login($scope.user.email, $scope.user.password)
.then(function() {
$state.go('success');
});
};
}]);
Index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Todo Application</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="css/style.css" rel="stylesheet">
</head>
<header ng-include="'views/header.html'"></header>
<body>
<ui-view></ui-view>
<script src="vendor/angular.js"></script>
<script src="vendor/angular-resource.js"></script>
<script src="vendor/angular-ui-router.js"></script>
<script src="js/app.js"></script>
<script type="text/javascript" src="js/services/auth.js"></script>
<script type="text/javascript" src="js/controllers/auth.js"></script>
<script src="js/services/lb-services.js"></script>
</body>
</html>
Also, in order to provide as much detail into the problem as possible here is a look at the errors presently in my console.
Thanks in advance for the help, it's greatly appreciated.
I believe that AuthService is some service you wrote yourself. You should use instead the utility provided by strongloop to generate the service from your server's models.
Authentication with loopback + angular is pretty straightforward like that.
Generate angular services from loopback server by running lb-ng . ./client/js/lb-services.js inside your server's root folder.
Then in angular, call MyUser.login({email: 'foo#bar.com', password: 'foobar'})
Done. If credentials are correct, the user will be authenticated for any further request (basically, the service memorizes the connection token, and sets it in the Authorization header each time a new request is made against your REST api).
Eventually, you may be interested in calling MyUser.isAuthenticated() to make your page behave differently if the user is, well, authenticated.
This is all documented here
You are using AuthService, which is user created service. It is abstraction over lb-services.js of loopback. You have to generate lb-services.js using lb command line.
Loopback angularjs Authentication : Login and registration
Steps:
Create new loopback project.
Generate lb-services.js and use it in angularjs project.
Use User.login() for login, User.create() for registration and User.isAuthenticated() to check user is login or not.
Best tutorial for loopback angularjs authentication

Dojo : Failed to load resource

I'm trying to follow this [dojo tutorial]1 , a very simple , but it doesn't run
work.
here is the Html code :
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script>
dojoConfig = {
parseOnLoad: true,
baseUrl: "http://localhost/arcgis_js_api/library/3.15/",
isDebug: true
};
</script>
<script src="http://localhost/arcgis_js_api/library/3.15/dojo/dojo.js"></script>
</head>
<body>
<div id="container">
</div>
<script>
require(["dijit/form/CheckBox"], function(CheckBoxk) {
var chbox = new CheckBoxk({
id: "chbox1",
checked: true
});
chbox.placeAt("container", "first");
});
</script>
</body>
</html>
and this is Google chrome output:
Unless you are hosting your own custom version of the ArcGIS API for JavaScript on your system (i.e. because you are using localhost), you should instead use ESRI's CDN to load the API resources.
Ex:
<link rel="stylesheet" href="https://js.arcgis.com/3.15/esri/css/esri.css">
<script src="https://js.arcgis.com/3.15/"></script>
Otherwise it appears you simply have a bad web server configuration on your system, i.e. "arcgis_js_api" doesn't point where you think it points. Check your web server log for more information about the 404.

Resources