I'm having an issue with Google Apps Script state tokens when called from a managed library. This means a The state token is invalid or has expired. Please try again.
error is always received is the state token is created from a sub function.
Here's some example code that would be in the library (you can add with project key MP9K5nBAvEJwbLYG58qx_coq9hSqx7jwh
)
var SCRIPT_ID = "1eC5VsM2vkJXa9slM40MTKTlfARGAGyK1myMCU3AB_-Ox_jGxQaoPM8P2";
// get a callback url to render in popup
function getAuthURL() {
var authorizeURL = getCallbackURL('testCallback');
return authorizeURL;
}
// generate a user callback url
function getCallbackURL(callback) {
var state = ScriptApp.newStateToken().withTimeout(3600).withMethod(callback).createToken();
return 'https://script.google.com/macros/d/'+SCRIPT_ID+'/usercallback?state='+state;
}
// generate login popup
function showLogin(doctype){
doctype.getUi().showDialog(
HtmlService
.createTemplate("<div><p><a href='<?=getAuthURL()?>' id='start-auth'><?=getAuthURL()?></a></p>" +
"<p><a href='<?=getAuthURLStored()?>' id='start-auth'><?=getAuthURLStored()?></a></p></div>")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE)
);
}
// dummy callback function
function testCallback(e){
return HtmlService.createHtmlOutput('<b>Success. You can close this window. !</b>')
}
/*
Rather than using dynamic state url storing the callback url and getting from property
(you could set a script trigger to refresh this every 24 hours)
*/
function getAuthURLStored() {
var authorizeURL = getSetCallbackURL();
return authorizeURL;
}
function setCallbackURL(){
PropertiesService.getScriptProperties().setProperty('callbackURL', getCallbackURL('testCallback'))
}
function getSetCallbackURL(){
return PropertiesService.getScriptProperties().getProperty('callbackURL')
}
which could be called in a Google Document as (assuming managed library identifier is statetest.
function testFunction() {
statetest.showLogin(DocumentApp);
}
When testFunction
is run the dialog in the Document presents two urls, the first with a dynamic state url is invalid the second with a stored state token works.
Is this a bug or expected behaviour?
An example to use a library to handle an authentication flow is to publish a web app from the library which the user is directed to to being the authentication process.
What you are trying to do currently isn't supported. Specifically creating a state token in a library running in an outer script, but having the callback go straight to the library. As of today the callback must always be directed at the outer script, which can then delegate back to the library as needed. You can open a feature request on the issue tracker to support your use case and we'll consider it further.