Initiating the Google+ Sign-In flow with JavaScript not working - javascript

I'm following the current tutorial and for some reason when ever I click on the Sign in with Google button nothing seems to happen and I'm not entirely sure why. Here is the code:
<html>
<head>
<title></title>
<script src="https://apis.google.com/js/client:platform.js" async defer></script>
</head>
<body>
<meta name="google-signin-clientid" content="782332402251-os0n348u3v5vaq5kff87f5pc65ib6i19.apps.googleusercontent.com" />
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/plus.login" />
<meta name="google-signin-requestvisibleactions" content="http://schema.org/AddAction" />
<meta name="google-signin-cookiepolicy" content="single_host_origin" />
<script src="https://apis.google.com/js/client:platform.js?onload=render" async defer>
/* Executed when the APIs finish loading */
function render()
{
// Additional params including the callback, the rest of the params will
// come from the page-level configuration.
var additionalParams = {
'callback': signinCallback
};
// Attach a click listener to a button to trigger the flow.
var signinButton = document.getElementById('signinButton');
signinButton.addEventListener('click', function() {
gapi.auth.signIn(additionalParams); // Will use page level configuration
});
}
function signinCallback(authResult)
{
if (authResult['status']['signed_in']) {
// Update the app to reflect a signed in user
// Hide the sign-in button now that the user is authorized, for example:
document.getElementById('signinButton').setAttribute('style', 'display: none');
} else {
// Update the app to reflect a signed out user
// Possible error values:
// "user_signed_out" - User is signed-out
// "access_denied" - User denied access to your app
// "immediate_failed" - Could not automatically log in the user
console.log('Sign-in state: ' + authResult['error']);
}
}
</script>
<button id="signinButton">Sign in with Google</button>
</body>
</html>
Any idea where I'm going wrong?

Looks like a mistake in the tutorial. Emedding Javascript within a script tag with a src attribute is not valid in HTML5. You need to move your code into a separate script tag.
<script type="text/javascript">
// your code here
</script>
See here - http://jsfiddle.net/7umb41z2/

Related

Call a function on Input Completion

I have a name input on 1.html.
I need to call a function where the input will be stored after completion, and when the person clicks ~next~ to go to the next page (2.html), whatever was stored appears there.
Example:
~1.html~
What's your name?
~input~ John ~input~
~2.html~
Hi, John! How can i help you?
I know i can use Session Storage to do it, but i'm not sure on how to proceed.
Here's what i have:
1.html
<p>"Whats Your Name?"</p>
<input id="your-name-input" type="text">
<a href="2.html">
<button id="next-button">Next</button>
<script>
nextButton = document.getElementById("next-button);
nextButton.addEventListener("click", () => {
var name = document.getElementbyId("your-name-input").value;
if(name !== "") {
sessionStorage.setItem("name", name);
} else {
alert("Please fill yout name")
});
</script>
And then, on 2.html i have:
<p id="user-name"></p>
What i'm trying to do, is to put inside the <p>, the following greeting:
Hi (name.value), how can i help you?
How can i call a function that loads the name value on the 2.html page when the page loads?
The below code should work. There are a few things missing in your code, not sure if you copied everything in.
In either case, the below works for me. You just need to update the link in the window.location = syntax. When you do that, it will take your stored value to the new page in the same tab, and display it using the script code in 2.html.
Code in 1.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
<title>Your name test</title>
</head>
<body>
<p>Whats Your Name?</p>
<input id="your-name-input" type="text">
<button id="next-button">Next</button>
<script>
const nextButton = document.getElementById("next-button");
const input = document.getElementById("your-name-input");
nextButton.addEventListener("click", () => {
const name = input.value;
if(name !== "") {
sessionStorage.setItem("name", name);
window.location = "<link to your 2.html file>";
} else {
alert("Please fill your name")
}
});
</script>
</body>
<footer>
</footer>
</html>
Code in 2.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
<title>See, it works</title>
</head>
<body>
<p id="user-name"></p>
<script>
const displayText = document.getElementById("user-name");
const storedValue = sessionStorage.getItem("name");
console.log(storedValue);
window.addEventListener("load", () => {
displayText.innerHTML = "Hi " + storedValue;
})
</script>
</body>
<footer>
</footer>
</html>
Original ans to original question:
You could use an addEventListener with an IF statement for your 'next' button and then the code you already have for localStorage.
Depending on what you need from your page, you could also use sessionStorage - that one doesn't save the input forever so might save, albeit limited, space on your user's computer.
I don't see the HTML for your button yet. But assuming you have it, here's an option for the rest of your code in 1.html.
Inside 1.html script tag:
nextButton = document.getElementById("yourButtonID");
nextButton.addEventListener("click", () => {
var name = document.getElementById("your-name-input").value;
if(name !== "") { // if input is not empty
localStorage.setItem("name", name); // set the value in localStorage
} else {
alert("Please fill your name")} // else, display an alert (if you like)
});

Angular 5 Google Signin into component

I've implemented Client Google Signin using my API Key into my html page. When I insert all the necessay tags and functions into index.html it works perfectly, but when it comes to insert the Google Signin button into a component, it is not even shown.
So, if this is how it works in a simple html page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Google Signin out Demo</title>
<script src="https://apis.google.com/js/platform.js" async defer>
</script>
<meta name="google-signin-client_id" content="myprivateid.apps.googleusercontent.com">
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn"></div><br />
Sign out
<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.
console.log(profile);
}
function signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
}
</script>
</body>
</html>
If I want to insert into an Angular component and leave the things as similar as I can I would left the meta-tag and the google script into the index.html and then insert the button in a component. It is not even shown. What am I getting wrong?
<!DOCTYPE html>
<html>
<head>
<script src="https://apis.google.com/js/platform.js" async defer>
</script>
<meta name="google-signin-client_id" content="myprivateid.apps.googleusercontent.com">
</head>
<body>
<app-root></app-root>
</body>
</html>
and in the specific template of the component in which I want the button to appear I insert:
<div class="g-signin2" data-onsuccess="onSignIn"></div><br />
Sign out
Apart from the little javascript code I must add, the button is not even shown.
How can I fix it without installing other npm components?

Recording State of iframe(url) from within an Office Add-in

So I am developing an office add in which will essentially contain an iframe which will be running an application we own.
The problem is, I want to contantly record the url of the iframe so that i can save this to the addin state, aloowing us to use that information to load the iframe to the correct url each time the addin is reopened.
I cant figure out a way to output the url from within the iframe each time it changes? here is a sample of what i have, this doesnt contain the application just a couple of sample pages:
Home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title></title>
<script src="../Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<script src="../Scripts/FabricUI/MessageBanner.js" type="text/javascript"></script>
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<link href="Home.css" rel="stylesheet" type="text/css" />
<script src="Home.js" type="text/javascript"></script>
<!-- For the Office UI Fabric, go to https://aka.ms/office-ui-fabric to learn more. -->
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.1.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.1.0/fabric.components.min.css">
</head>
<body>
</body>
</html>
Home.js
(function () {
"use strict";
// The initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
var iframew = document.createElement('iframe');
iframew.src = '../SecondPage/SecondPage.html';
iframew.id = 'iframe1';
iframew.onload = iframeLoaded(this.contentWindow.location.href);
document.body.appendChild(iframew);
});
};
// Helper function for displaying notifications
function iframeLoaded(location) {
console.log("log", location);
}
})();
Cant understand why people are downvoting this question, it was a genuine issue
Anyway, for anyone interested I solved this by attaching a a function after the iframe loads which outputs the url of the iframe at set interval periods
var iframew = document.createElement('iframe');
iframew.id = 'iframe1';
var baseUrl = '#YOUR BASE URL#';
let openUrl = getProperty('openurl');
if (!openUrl) {
console.log('No saved url');
iframew.src = baseUrl;
}
else {
console.log('saved url');
console.log(openUrl);
iframew.src = openUrl;
}
//when iframe loads attach function to save at interval
iframew.addEventListener('load', function () { setInterval(function () { iframeLoaded(iframew.contentWindow.location.hash, iframew.contentWindow.location.href); }, 4000); });
document.body.appendChild(iframew);
here is the iframeLoaded Function which also does some manipulation of the url and calles another function which saves the url to the doocument settings of the add-in:
function iframeLoaded(hash, location) {
//if not in an analysis dont save
if (hash.indexOf('#/dataset/') !== -1 ) {
console.log("Same url")
return
}
//remove # from hash
hash = hash.substr(1);
//concatenate base and hash
let newUrl = baseUrl + hash;
console.log(hash)
console.log(newUrl);
//save
if (Office.context.document.settings) {
saveProperty('openurl', newUrl);
}
}

How to load different pages in O365 mail app based on regex

I am creating an O365 app and I have 2 .aspx files, when the user clicks on the O365 mail app, I want each of these pages to be loaded based on the subject of the mail.
Scenario 1: Mail subject contains '#'
result: load page1
Scenario 2: Mail subject does not contain '#'
result: load page2
I have tried having an intermediate .js file where I have written the logic,
but when I do window.location = "path_to_aspx_file",
only the html is loaded but the js files do not run.
My current implementation:
I have LandingLogic.js
(function () {
"use strict";
//The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
var item = Office.cast.item.toItemRead(Office.context.mailbox.item);
var sub = item.subject;
if (sub.indexOf("some text") > -1) {
window.location = "http://localhost:51776/File1.aspx";
}
else {
window.location = "http://localhost:51776/File2.aspx";
}
});
};
})();
After a bit of fumbling around.
I am able to navigate to each of these files now, but I am not sure how to access the mail subject from File1.aspx and File2.aspx.
Did you initialize the Office context before you using Office JavaScript API to get the subject? To redirect the HTML page easily, we can include the JavaScript like below:
Home.js:
/// <reference path="../App.js" />
(function () {
"use strict";
// The Office initialize function must be run each time a new page is loaded
Office.initialize = function (reason) {
$(document).ready(function () {
app.initialize();
RedirectHTMLPage();
});
};
function RedirectHTMLPage() {
var subject = Office.context.mailbox.item.subject;
if (subject.indexOf("#") != -1) {
window.location.href = "https://localhost:44300/page1.aspx";
} else {
window.location.href = "https://localhost:44300/page2.aspx";
}
}
})();
The HTML page for redirecting:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<title></title>
<script src="../../Scripts/jquery-1.9.1.js" type="text/javascript"></script>
<link href="../../Content/Office.css" rel="stylesheet" type="text/css" />
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<!-- To enable offline debugging using a local reference to Office.js, use: -->
<!-- <script src="../../Scripts/Office/MicrosoftAjax.js" type="text/javascript"></script> -->
<!-- <script src="../../Scripts/Office/1/office.js" type="text/javascript"></script> -->
<link href="../App.css" rel="stylesheet" type="text/css" />
<script src="../App.js" type="text/javascript"></script>
<link href="Home.css" rel="stylesheet" type="text/css" />
<script src="Home.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
I have tried having an intermediate .js file where I have written the logic, but when I do window.load = "path_to_aspx_file", only the html is loaded but the js files do not run.
Would you mind sharing the detail you using the “window.load”?
Fei Xue answer is correct . if you want to get subject from file2.aspx , add office.js reference and access subject same as file1.aspx inside the Office.initialize event
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>

Google+ API doesnt return access_token Javascript

We have an application that relies upon Google to authenticate its users against our google apps account and then do some serverside verification and group lookups.
Recently google changed the name of the object that held the access_token variable which we require to authenticate. In the docs (https://developers.google.com/identity/sign-in/web/reference#googleusergetbasicprofile) it says that access_token is available from the getAuthResponse() method, however when i use this it comes back as undefined. Inspecting the object after console.log() reveals all the other fields mentioned except access_token. I'm worried that Google will change the object again in the future and leave us without our application.
Here is the code.
<head>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<meta name="google-signin-client_id" content="XXX.apps.googleusercontent.com">
<script>
//This happens after the user has authenticated with Google and has been passed
//back to the page
function onSignIn(googleUser) {
//Check to see whether the user is trying to sign out.
if (window.location.href.indexOf("signOut=1") !== -1) {
//Sign them out of the application.
signOut();
//redirect them to the same page, without the signOut query string so they can log back in if want
window.location.href='googlesigninform.html'
return false;
}
//Grab the token, access token and email.
var _id = googleUser.getAuthResponse().id_token; //This works
var _accessToken = googleUser.Ka.access_token; //This works but changed from googleUser.B.access_token
var profile = googleUser.getBasicProfile(); //Works
console.log(googleUser.access_token); //Undefined
console.log(googleUser.getAuthResponse().access_token);//Undefined
//Make a post request to the API
makePostRequest(_id, _accessToken, profile.getEmail());
}
What is the correct way to access the access_token variable?
If you need to use access token you are using the wrong type of google signin flow.
You should follow this page: https://developers.google.com/identity/sign-in/web/server-side-flow
What you did implement is google Sign-In to identify users (https://developers.google.com/identity/sign-in/web/)
Which only provides a unique id per user because it is meant to authenticate the user for your own service and not to give an access token to use for other Google services later on.
I believe your problem is that your application is lacking the necessary google-signin-scope.
To answer your question i created an app from the ground using the Google Developer Console. The application is very simple like the one this this tutorial.
The entire application consists of a simple HTML that loads the google API and has a callback called onSignIn (like yours).
Here's the entide code of the application:
<html lang="en">
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="PLACE_YOUR_ID_HERE.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
<script>
function onSignIn(googleUser) {
var response = googleUser.getAuthResponse(),
idToken = response['id_token'],
accessToken = response['access_token'];
console.dir('id token: ' + idToken);
console.dir('access token: ' + accessToken);
}
</script>
</body>
</html>
As you can see, the difference between my app and yours is that yours is lacking the first META attribute.
Well i have a hack work around that gets the access_token from the variable.
function findAccessToken(googleUser) {
var returnValue;
Object.getOwnPropertyNames(googleUser).forEach(function (val, idx, array) {
console.log(val + ' -> ' + googleUser[val]);
Object.getOwnPropertyNames(googleUser[val]).forEach(function (vals, idxs, arrays) {
if (vals === "access_token") {
console.log("true");
returnValue = googleUser[val][vals];
}
});
});
return returnValue;
}
Surely this can't be the most elegant solution. If someone could point in the righter direction that would be good.
Here is the code for sign in using google.
<html lang="en">
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
<script>
function onSignIn(googleUser) {
// Useful data for your client-side scripts:
var profile = googleUser.getBasicProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
console.log("Name: " + profile.getName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: " + profile.getEmail());
// The ID token you need to pass to your backend:
var id_token = googleUser.getAuthResponse().id_token;
console.log("ID Token: " + id_token);
};
</script>
</body>
</html>
Try this
var _access_token = GoogleUser.getAuthResponse().access_token

Categories