How to resolve Cloud Function Error:401 Unauthorized - authentication

I have coded an Apps Script that creates an event in the Calendar.
Apps Script is stand alone, and event in also created in my personal Gmail account.
This Script is linked to GCP project linked to same account as Script.
Oauth consent screen is created in the GCP account and also credentials for Oauth2.0 client ID.
Now I created a cloud function to call this appsScript but it is giving an Error:401
following is code for the cloud function
let message = req.query.message || req.body.message || 'Hello World!';
const axios = require('axios');
const {google} = require('googleapis');
//Authorization
const { GoogleAuth } = require('google-auth-library');
const auth1 = new GoogleAuth({
keyFile: 'credentials.json',
scopes: ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.metadata'
, 'https://www.googleapis.com/auth/calendar','https://www.googleapis.com/auth/calendar.events' ],
});
const drive = google.drive({version: 'v3', auth: auth1 });
const calendar = google.calendar({version : "v3"});
//calling formSchedule function with all the variables
async function formSchedule(eventDate,claimId, garageId, claimDet,startTime,cEmailG){
//Schedule Meeting Json Data
var evDurtion=30;
var startDateTime = startTime;
var endDateTime=new Date(startDateTime.getTime()+(evDurtion*60000));
// console.log(endDateTime)
var subject="Claim ID : "+claimId+' - Call';
var attendees=[{
"email": garageId,
},
];
var eventData={
"summary":subject,
'start': {
'dateTime': startDateTime,
'timeZone': 'Asia/Kolkata'
},
'end': {
'dateTime': endDateTime,
'timeZone': 'Asia/Kolkata'
},
"attendees":attendees,
"conferenceData": {
"createRequest": {
"conferenceSolutionKey": {
"type": "hangoutsMeet"
},
"status": {
"statusCode": "success"
},
"requestId": "test1235"
}
},
"description":claimDet,
"defaultReminders": [
{
"method": "popup",
"minutes": "5"
}
]
}
console.log("after all variables initialization")
// Schedule Meeting
axios({
method: "post",
url : //API Executable deployed Apps Script link,
data: {
'eventdata' : eventData,
'serviceId' : cEmailG
},
headers: {
'Content-Type': 'text/plain;charset=utf-8',
},
}).then(function (response) {
try{
console.log('Event Added Successfully.')
}
catch (error){
console.log('------error-----',error)
}
})
}
res.status(200).send(message);
};```

Related

React Blitz.js 3rd party auth failing with passport-azure-ad

I'm attempting to swap the default auth scheme in Blitz.js with a passport-azure-ad scheme, using the OIDCStrategy. I'm getting an error that I'm not sure about and would appreciate any help! I've created a new file under src/pages/auth/openid.tsx and into inserted the following code:
import { passportAuth } from "#blitzjs/auth"
import { api } from "src/blitz-server"
import { OIDCStrategy } from "passport-azure-ad"
const users: Array<{ oid: string }> = []
var findByOid = function (oid, fn) {
console.log("failing")
for (var i = 0, len = users.length; i < len; i++) {
const user = users[i]
console.log("we are using user: ", user)
if (user && user.oid === oid) {
return fn(null, user)
}
}
return fn(null, null)
}
export default api(
passportAuth({
successRedirectUrl: "/",
errorRedirectUrl: "/",
strategies: [
{
strategy: new OIDCStrategy(
{
identityMetadata:
"https://login.microsoftonline.com/<tenant-nam>.onmicrosoft.com/v2.0/.well-known/openid-configuration",
clientID: <client-id>,
responseType: "code id_token",
responseMode: "form_post",
redirectUrl: "http://localhost:3000/auth/openid/callback",
allowHttpForRedirectUrl: true,
clientSecret: "<client-secret>",
validateIssuer: false,
passReqToCallback: true,
scope: ["profile", "offline_access", "https://graph.microsoft.com/mail.read"],
loggingLevel: "info",
nonceMaxAmount: 5,
useCookieInsteadOfSession: false,
cookieEncryptionKeys: [
{ key: "12345678901234567890123456789012", iv: "123456789012" },
{ key: "abcdefghijklmnopqrstuvwxyzabcdef", iv: "abcdefghijkl" },
],
},
function (iss, sub, profile, accessToken, refreshToken, done) {
if (!profile.oid) {
return done(new Error("No oid found"), null)
}
// asynchronous verification, for effect...
process.nextTick(function () {
findByOid(profile.oid, function (err, user) {
if (err) {
return done(err)
}
if (!user) {
// "Auto-registration"
users.push(profile)
return done(null, profile)
}
return done(null, user)
})
})
}
),
},
],
})
)
I believe the configuration is good because I can run the example from passport-azure-ad from the github examples. The only change I make is that I set redirectUrl: "http://localhost:3000/auth/openid/callback", instead of redirectUrl: ".../return", per the blitz.js third party auth documentation. The tenantname, client_id, client_secret are redacted but I do set them to the correct values. I have also verified that the app registration is correctly set with the correct redirect uri.
I run blitz dev and when I go to the http://localhost:3000/auth/openid route I get the following error.
Here is the console output that is produced:
As you can see there is a Module not found: Can't resolve './src/build', this error only occurs if I go to the auth/openid page but the app is able to load.

swagger-ui-express persistAuthorization not working

I have a very simple sample code using swagger-ui-express:
const express = require("express");
app = express();
app.listen(3000);
const swaggerUi = require('swagger-ui-express');
var options = {
swaggerOptions: {
persistAuthorization: true
}
};
app.use('/doc',
swaggerUi.serve, swaggerUi.setup(
{
"swagger": "2.0",
"info": {
"title": "Simple API overview",
"version": "v2"
},
securityDefinitions: {
BearerAuth: {
type: 'apiKey',
in: 'header',
name: 'Authorization'
},
},
}
,
options
)
);
I am not able to mak persistAuthorization work, after entering anything in the authorization field, when refreshing the web page the authorization is deleted.
The code follows the documentation in https://www.npmjs.com/package/swagger-ui-express
And the persistAuthorization option is documented in https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/

How to execute Google Cloud Functions from Firebase Hosting?

I'm trying to create an Android project which can send notifications from one android device to another. For that purpose, I created a node.js file, it's working fine on the local server. But when I hosted it on Google Cloud Platform, it shows Page Not Found. It is not able to call Google Function from hosting. It is looking for or executing index.html but it should execute index.js, which is in functions directory which was created while initializing the project with Firebase.
I took the reference from this video: https://youtu.be/pnysHgQvOiM?list=PLk7v1Z2rk4hjM2NPKqtWQ_ndCuoqUj5Hh
index.js file
const functions = require('firebase-functions');
var {google} = require('googleapis')
var MESSAGING_SCOPE ="https://www.googleapis.com/auth/firebase.messaging"
var SCOPES = [MESSAGING_SCOPE]
var express = require('express')
var app = express();
var bodyParser = require('body-parser');
var router = express.Router();
var request = require('request');
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
router.post('/send',function(req,res){
getAccessToken().then(function(access_token){
var title = req.body.title;
var body = req.body.body;
var token = req.body.token;
request.post({
headers:{
Authorization: 'Bearer '+ access_token
}, url:
"https://fcm.googleapis.com/v1/projects/my_project_name/messages:send",
body: JSON.stringify(
{
"message":{
"token" : token,
"notification" : {
"body" : body,
"title" : title
}
}
}
)
},function(error,reponse,body){
res.end(body);
console.log(body);
});
});
});
app.use('/api',router);
function getAccessToken()
{
return new Promise(function(resolve,reject){
var key= require("./service-account.json");
var jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
SCOPES,
null
);
jwtClient.authorize(function(error,tokens){
if(error)
{
reject(error)
}
resolve(tokens.access_token)
// console.log(tokens.access_token)
});
jwtClient.authorize(function(error,tokens){
if(error)
{
reject(error)
}
resolve(tokens.access_token)
console.log(tokens.access_token)
});
});
}
exports.api = functions.https.onRequest(app);
firebase.json
{
"hosting":
{
"public": "public",
"rewrites": [
{
"source": "/api/send",
"functions": "api"
}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
This code is working fine with using http://localhost:8085/api/send but it is not working as https://my_project_name.firebaseapp.com/api/send

Alexa Skills: Lambda function to read contents from a file in S3

I have an Alexa Skill that tries to read the contents from a file stored in S3. The test event for the Lambda function for Alexa Start Session is successful. I understand that there is something wrong with my CompletedMyIntentHandler but I can't quite seem to figure it out. Any help on it is much appreciated. The lambda function takes help from https://github.com/alexa/alexa-cookbook/blob/master/aws/Amazon-S3/read/. Find my Lambda function below;
const Alexa = require('ask-sdk');
// 1. Text strings =====================================================================================================
// Modify these strings and messages to change the behavior of your Lambda function
const helpOutput = 'You can demonstrate the S3 Storage read capability by saying "Hello".';
const helpReprompt = 'Try saying "Hello World".';
var myBucket = 'jailalita'; // replace with your own bucket name!
var myObject = 'hello.txt'; // replace with your own file name!
// 2. Intent Handlers =============================================
const CompletedMyIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'MyIntent';
},
handle(handlerInput) {
console.log('My Intent - handle');
const responseBuilder = handlerInput.responseBuilder;
const speechOutput = MyIntent();
return responseBuilder
.speak(speechOutput)
.getResponse();
},
};
const HelpHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
return responseBuilder
.speak(helpOutput)
.reprompt(helpReprompt)
.getResponse();
},
};
const CancelStopHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest' && (request.intent.name === 'AMAZON.CancelIntent' || request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const responseBuilder = handlerInput.responseBuilder;
const speechOutput = 'Okay, talk to you later! ';
return responseBuilder
.speak(speechOutput)
.withShouldEndSession(true)
.getResponse();
},
};
const SessionEndedHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
const request = handlerInput.requestEnvelope.request;
console.log(`Original Request was: ${JSON.stringify(request, null, 2)}`);
console.log(`Error handled: ${error}`);
return handlerInput.responseBuilder
.speak('Sorry, I can not understand the command. Please say again.')
.reprompt('Sorry, I can not understand the command. Please say again.')
.getResponse();
},
};
// 3. Helper Function =================================================================================================
function MyIntent() {
var myParams = {
Bucket: myBucket,
Key: myObject
};
S3read(myParams, myResult => {
console.log("sent : " + JSON.stringify(myParams));
console.log("received : " + myResult);
var speech = this.response.speak('The S 3 file says, ' + myResult );
return speech;
}
);
}
function S3read(params, callback) {
// call AWS S3
var AWS = require('aws-sdk');
var s3 = new AWS.S3();
s3.getObject(params, function(err, data) {
if(err) { console.log(err, err.stack); }
else {
var fileText = data.Body.toString(); // this is the complete file contents
callback(fileText);
}
});
}
// 4. Exports handler function and setup ===================================================
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
//LaunchRequestHandler,
CompletedMyIntentHandler,
HelpHandler,
CancelStopHandler,
SessionEndedHandler,
)
.addErrorHandlers(ErrorHandler)
.lambda();
JSON Input
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.e6f74d95-8d55-4aac-ade0-dd4ff4ed4f04",
"application": {
"applicationId": "amzn1.ask.skill.5edd47bc-525d-4ef4-9b6e-a83a7e79744f"
},
"user": {
"userId": "amzn1.ask.account.AF4SLRK5TC4SDSHL7LGK2IB6SMXCPGS7Y6YKYLPDGWRE7CA3K6MCKVVUW2OFMVCWJFXZDQBSYY5Z2RXZWQAJLDCMR3SXYCVA7ZARDRNQXA3TXBM4ILP77FKNOO4MCVPLWHIXW3QNZCRYPDQ7CCBP6QT7GMTBMQX2BVCNS22SZL4MC6WB7GDS44XN2DKGJQBMGIDQ3O7RBYD6GAI"
}
},
"context": {
"System": {
"application": {
"applicationId": "amzn1.ask.skill.5edd47bc-525d-4ef4-9b6e-a83a7e79744f"
},
"user": {
"userId": "amzn1.ask.account.AF4SLRK5TC4SDSHL7LGK2IB6SMXCPGS7Y6YKYLPDGWRE7CA3K6MCKVVUW2OFMVCWJFXZDQBSYY5Z2RXZWQAJLDCMR3SXYCVA7ZARDRNQXA3TXBM4ILP77FKNOO4MCVPLWHIXW3QNZCRYPDQ7CCBP6QT7GMTBMQX2BVCNS22SZL4MC6WB7GDS44XN2DKGJQBMGIDQ3O7RBYD6GAI"
},
"device": {
"deviceId": "amzn1.ask.device.AETD2DDUWNTWA5BNNDFHCRT26SLOZUTZUFJ5P3OEQGDCWWDSFWPKNONGMT4KZAJPUB6ZRD3YVCDEVFAGPLXHVP6XESWS6BKEYZHZRXT25QNK2RTFNUG4PKD347P5DAWE2H4WQLGTQVLNQ5JNFGHFUSUC3X7Q",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLjVlZGQ0N2JjLTUyNWQtNGVmNC05YjZlLWE4M2E3ZTc5NzQ0ZiIsImV4cCI6MTUzMDUxMzU2NCwiaWF0IjoxNTMwNTA5OTY0LCJuYmYiOjE1MzA1MDk5NjQsInByaXZhdGVDbGFpbXMiOnsiY29uc2VudFRva2VuIjpudWxsLCJkZXZpY2VJZCI6ImFtem4xLmFzay5kZXZpY2UuQUVURDJERFVXTlRXQTVCTk5ERkhDUlQyNlNMT1pVVFpVRko1UDNPRVFHRENXV0RTRldQS05PTkdNVDRLWkFKUFVCNlpSRDNZVkNERVZGQUdQTFhIVlA2WEVTV1M2QktFWVpIWlJYVDI1UU5LMlJURk5VRzRQS0QzNDdQNURBV0UySDRXUUxHVFFWTE5RNUpORkdIRlVTVUMzWDdRIiwidXNlcklkIjoiYW16bjEuYXNrLmFjY291bnQuQUY0U0xSSzVUQzRTRFNITDdMR0sySUI2U01YQ1BHUzdZNllLWUxQREdXUkU3Q0EzSzZNQ0tWVlVXMk9GTVZDV0pGWFpEUUJTWVk1WjJSWFpXUUFKTERDTVIzU1hZQ1ZBN1pBUkRSTlFYQTNUWEJNNElMUDc3RktOT080TUNWUExXSElYVzNRTlpDUllQRFE3Q0NCUDZRVDdHTVRCTVFYMkJWQ05TMjJTWkw0TUM2V0I3R0RTNDRYTjJES0dKUUJNR0lEUTNPN1JCWUQ2R0FJIn19.Fc-aAcaf4qTgf489cQsZ44KTq-yZ-xMJCBenq9DbpppkMgSscF0NodGYTK967AcGblwqOFqcwIC1PvGmISER9oDH5TIhKF1kLsTimRHRKsttElRl7FIEvki-sKLD4VTeStTKM-w5laBm6urAzlCXpJySU-InVH5_qE0M5LHnLZRrE_qy7EmIq2vsrq2Cekve-gQ3Y3ImW3_0b7ikg6gwO6si-O0IxXO6hxS5sTuQH4f4aRybHVO3jflHD7g7pGPFzfkpc_tg6KFkhFv6CMvkx25A2u7iO7vVQpMHdj-_2ZM0ZmO9JuP-v7ydKYT_1IDjfpZKfvgIGyYsNfCPDY5F2Q"
}
},
"request": {
"type": "LaunchRequest",
"requestId": "amzn1.echo-api.request.12ef23e3-a7e5-48a4-90f9-de9c253f72b9",
"timestamp": "2018-07-02T05:39:24Z",
"locale": "en-US",
"shouldLinkResultBeReturned": false
}
}
JSON Output
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can not understand the command. Please say again.</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can not understand the command. Please say again.</speak>"
}
},
"shouldEndSession": false
},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.0 Node/v8.10.0"
}
}
JSON Editor
{
"interactionModel": {
"languageModel": {
"invocationName": "hello world",
"intents": [
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "MyIntent",
"slots": [],
"samples": [
"hello"
]
}
],
"types": []
}
}
}
You can't build your response and return inside the S3Read function as it's an async call to an external service. You need to wait for that call using async/await and once you get a value then craft the response and return.

Issue with mocking ajax request

I am writing a test for webclient viewmodel in Qunit and used Mockjax for moking ajax request, but it seems i am doing something wrong while moking, please help me to solve the following problem.
function WebmailViewModel() {
// Data
var self = this;
self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenMailData = ko.observable();
// Behaviours
self.goToFolder = function(folder) {
self.chosenFolderId(folder);
self.chosenMailData(null); // Stop showing a mail
$.post('/mail', { folder: folder }, function(returnedData) {
self.chosenFolderData(returnedData);
});
}
self.goToMail = function(mail) {
self.chosenFolderId(mail.folder);
self.chosenFolderData(null); // Stop showing a folder
$.get("/mail", { mailId: mail.id }, self.chosenMailData);
};
self.goToFolder('Inbox');
};
$(function() {
ko.applyBindings(new WebmailViewModel());
});
test("web mail client test", function() {
stop(2);
var returnedData = {
"from": "deba#tieto.com",
"to": "test1#tieto.com",
"subject": "Subject1",
"date": "22/05/2014"
};
vm = new WebmailViewModel();
$.mockjax({
url: "/mail",
contentType: "application/json",
responseTime: 0,
response: function (settings) {
this.responseText = {"from": "deba#xyz.com", "to": "test1#xyz.com", "subject":"Subject1", "date":"22/05/2014"};
start();
}
});
vm.goToFolder('Inbox');
setTimeout(function() {
deepEqual(vm.chosenFolderData,returnedData, "Two objects can be the same in value" );
start();
}, 150);
});
Test Result:
Two objects can be the same in valueExpected: {
"date": "22/05/2014",
"from": "deba#tieto.com",
"subject": "Subject1",
"to": "test1#tieto.com"
}
Result: function c( ){
[code]
}
Diff: {
"date": "22/05/2014",
"from": "deba#tieto.com",
"subject": "Subject1",
"to": "test1#tieto.com"
function c( ){
[code]
}
Source: at Anonymous function (file:///C:/Users/dasssdeb/Desktop/JS%20Tests/QUnit/tests/tests.js:174:8)
I belive issue is with moking the ajax request. please help me with your valuable experience.
Your mockjax setup must come before your source code. In the code above you initialize the WebmailViewModel (which performs ajax requests) before you set up the mockjax request handler. Try structuring things like this instead:
// SOURCE CODE
// in your source code you will need to have a callback for your WebmailViewModel method arguments...
function WebmailViewModel() {
// ...
// Behaviours
self.goToFolder = function(folder, callback) {
self.chosenFolderId(folder);
self.chosenMailData(null); // Stop showing a mail
$.post('/mail', { folder: folder }, function(returnedData) {
self.chosenFolderData(returnedData);
callback(returnedData);
});
}
self.goToMail = function(mail) {
self.chosenFolderId(mail.folder);
self.chosenFolderData(null); // Stop showing a folder
$.get("/mail", { mailId: mail.id }, function(returnedData) {
self.chosenMailData(returnedData);
callback(returnedData);
});
};
};
Now you can create your test code with callbacks when they finish to hook your assertions into...
// TEST CODE
// Set up the request handler first...
$.mockjax({
url: "/mail",
contentType: "application/json",
responseTime: 0,
response: function (settings) {
this.responseText = {"from": "deba#xyz.com", "to": "test1#xyz.com", "subject":"Subject1", "date":"22/05/2014"};
}
});
// then create your test...
test("web mail client test", function() {
stop();
var returnedData = {
"from": "deba#tieto.com",
"to": "test1#tieto.com",
"subject": "Subject1",
"date": "22/05/2014"
};
vm = new WebmailViewModel();
vm.goToFolder('Inbox', function(returnedData) {
// this is the callback for when going to the folder finishes...
deepEqual(vm.chosenFolderData, returnedData, "Two objects can be the same in value" );
start();
});
});