How can I get Google drive API to authenticate? - javascript

I am struggling a lot to get my authentication to work for Google drive api.
This is my current code.
const drive = google.drive({
version: 'v3',
auth: new google.auth.GoogleAuth({
keyFile: 'google-cloud-credentials.json',
scopes: ['https://www.googleapis.com/auth/drive.file'],
}),
});
No matter what I try, I get the error "ENOENT: no such file or directory, open '/var/task/google-cloud-credentials.json'"
I've also tried the following:
keyFile: path.resolve(__dirname, 'google-cloud-credentials.json'),
keyFile: './google-cloud-credentials.json',
keyFile: '../google-cloud-credentials.json',
keyFile: '../../google-cloud-credentials.json',
I should mention that I'm also deploying with with Serverless but in the past I've been able to get this to work.

So I found in the type definition for GoogleAuth that you can simply use credentials which takes the body of the credentials rather than keyFile which takes the path.
After that I just simply had to import JSON into my file and add it there.

that's not how you Auth. that's just creating google Auth object. you must fill it with credentials or it will do nothing.
maybe read the readme again. there's a standard implementation of oauth there. also feel free to ask a follow up

Related

Send Tokens through RPC API (Metamask)

I was doing a USDC transaction on the Ropsten network but in the Metamask documentation I didn't see any place where transactions with tokens were directly touched, I was trying some things I found without success. An example of what I found I took from How to send some custom tokens with MetaMask API?
ethereum.request({
method: "eth_sendTransaction",
params: [
{
from: ethereum.selectedAddress,
to: "0x07865c6E87B9F70255377e024ace6630C1Eaa37F",
data: tokenContract.methods
.transfer("My Wallet", "0.0001")
.encodeABI(),
}
]
});
The problem here is that tokenContract is not defined and I have no idea how to define it
I also found VERY old and really obsolete answers, where mostly web3js is used (And MetaMask doesn't allow to work with web3js anymore as far as I understand, I've already tried it).
In the example above, tokenContract is address of the token that you want to transfer. Each token contract is deployed on some address, see for example USDT or DAI.
Also, web3js does support MetaMask, see this answer for an example implementation. But MetaMask no longer injects web3js, so that you need to import web3js into the web app separately (previously it was possible to use web3 injected by MM).

Google Calendar API code not authenticating in Cloud Run

I've written a simple Calendar API call using the official NodeJS client: https://github.com/googleapis/google-api-nodejs-client#service-account-credentials
It works fine on my local machine, using a Service Account set up with Domain-Wide Delegation to create the event and invite a list of attendees on my behalf.
I set the credentials location using GOOGLE_APPLICATION_CREDENTIALS env var on my local machine, but do not set this on the Google Cloud Run service because it's supposedly automatic since I've associated the Service Account. This assumption seems true because I can call GoogleAuth functions and get back the expected service account name.
However, once I try to run it in Cloud Run, it throws the error:
Error: Service accounts cannot invite attendees without Domain-Wide Delegation of Authority.
At first I thought this was an issue with default credentials somehow loading the wrong service account.
I added logging directly before the event is called to see what account it is using:
const auth = new googleClient.auth.GoogleAuth({
clientOptions: {
subject: eventOwner
},
scopes: calendarScopes,
})
const serviceAcctName = (await auth.getCredentials())?.client_email
googleClient.options({
auth: auth
})
logger.info(`${serviceAcctName} acting as ${eventOwner}, using calendar ${calendarId}`)
const calendar = googleClient.calendar('v3')
const response = await calendar.events.insert(event)
The log output is exactly as expected, with the correct service account acting as the correct user on the correct calendar id.
I've double-checked that the account has domain-wide delegation of authority and the proper scopes, and it works fine on my local machine, so the only thing I can think of is something about the library's feature of grabbing default credentials in a Google environment is overwriting my googleClient.options() call. But I'm still confused because GoogleAuth functions still give the expected service account info when it grabs the 'default'.

How to configure security to allow swagger url to be accessed only with authentication in nodejs

I have integrated swagger in node and it is accessible on http://localhost:3002/api-docs. But the swagger ui is publicly accessible. I want to add authentication/security to access this route. When user hits http://localhost:3002/api-docs, it should show popup/prompt to enter username/password. If username and password is correct then only user should able to see swagger UI.
Possibly like as seen in below screenshot
I am using swagger-ui-express, and this is my code that I m using
import swaggerUi from 'swagger-ui-express';
import * as swaggerDocument from './swagger.json'
....
....
app.use("/api-docs",swaggerUi.serve,swaggerUi.setup(swaggerDocument));
I searched on the internet but didn't got any solution. I found one solution but that is in spring.
Thanks in advance !!
You can plug in a basic-auth middleware (e.g. https://github.com/LionC/express-basic-auth) to protect the swagger-ui route. If you use express-basic-auth, make sure to set the challenge option in order to force the browser to open a prompt:
const basicAuth = require('express-basic-auth');
app.use("/api-docs",basicAuth({
users: {'yourUser': 'yourPassword'},
challenge: true,
}), swaggerUi.serve, swaggerUi.setup(swaggerDocument));

Authenticating user in AWS Cognito User/Identity Pool with Google as identity provider

AWS provides two possible ways of dealing with Cognito:
"old one" via amazon-cognito-identity-js (and possibly amazon-cognito-auth-js) and
"new one" via aws-amplify (which inlcudes the above one)
After quite a bit of trouble and reverse engineering, I've successfully managed to sign in (receve back CognitoIdentityCredentials) using aws-amplify locally as part of the development effort.
The steps where (bear with me, as these are important for the questions to follow, and also might help someone):
Setup
Create a User Pool in Cognito console
Create a User Pool App Client in Cognito console
Create Google Web App in Google Console
Configure Google Web App to point to http://localhost:8080 (my local dev server)
Configure User Pool to use Google as an Identity Provider, supplying it with the Google Web App Client ID and Client secret from Google Console
Create an Identity Pool in Congnito console and configure it to work with Google as an Identity Provider, supplying Google Web App Client ID there as well
Implementation
Configure Amplify.Auth:
Amplify.configure({
Auth: {
identityPoolId: ,
region: ,
userPoolId: ,
userPoolWebClientId:
}
});
Inject Google API script:
const script = document.createElement('script');
script.src = 'https://apis.google.com/js/platform.js';
script.async = true;
script.onload = this.initGapi;
document.body.appendChild(script);
Init Google API:
window.gapi.load('auth2', function() {
window.gapi.auth2.init({
client_id: ,
scope: 'profile email openid'
});
});
Allow, on a button click, for a Google user to sing in:
const ga = window.gapi.auth2.getAuthInstance();
const googleUser = await ga.signIn();
const {id_token, expires_at} = googleUser.getAuthResponse();
const profile = googleUser.getBasicProfile();
User the profile, id_token, expires_at above to create a Cognito credentials session:
const user = {
email: profile.getEmail(),
name: profile.getName()
};
const credentials = await Auth.federatedSignIn(
'google',
{token: id_token, expires_at},
user
);
At this point a CognitoIdentityCredentials object was returned, properly populated, with token and all...
Problem
Unfortunately, aws-amplify adds a whopping 190K to my application webpack bundle (GZIPped, minified, optimized), which made me choke on my coffee.
Question 1
Can this somehow be reduced by a Babel plugin I'm missing (I'm guessing, no, since AWS is apparently still in 1995 and configures everything on a singleton Amplify and Auth objects).
Question 2
Have I made this unnecessarily complicated and there is a much more robust solution?
Question 3 (most important)
Can this be achieved using the "old way" amazon-cognito-identity-js, which is MUCH MUCH smaller?
I couldn't find, among all the (use cases)[https://github.com/aws/aws-amplify/tree/master/packages/amazon-cognito-identity-js/] a use case for social/federated login.
For me, the difference between
import Amplify from 'aws-amplify'
and
import Amplify from '#aws-amplify/core'
is ~500kB optimized and minified.
I think you also want
import Auth from '#aws-amplify/auth'
which adds only a little bit more.
But I agree, the aws-amplify package is really very large and it's not easy to figure out how to use the core components directly (e.g. aws-cognito-identity-js/es and aws-cognito-auth-js/es).
You could try using modularized exports in AWS amplify

Nodejs Google Drive API Shareable link

For my Nodejs project I'm using Google drive API for file sharing. But the problem is, the URL I'm getting from API is not a shareable link. So I have to go to the drive and switch on the sharing. Is there a way to get the shareable link or switch on the sharing with the java script code? Please give me a solution for this.
The comments were very helpful indeed, this solution is for the v3 of Google Drive and the Google Doc v1. I was using jwt auth for Service Account and the alternativeLink using Drive v2 is not sharable.
I'm assuming the auth process is known and complete. I'm writing the code in blocks so using await, promises, or callbacks is reader choice
First, you need to create a document:
google.docs({version: 'v1', auth});
docs.documents.create({title: "Your Title"}, (error, response) => {
if (error) return;
//So now you have the documentId
const {data: {documentId}} = response;
});
Now with the documentId we need to add a permission to the doc. The key is to grant permission to anyone. The doc explains anyone doesn't need an email or a user.
const resource = {"role": "reader", "type": "anyone"};
drive.permissions.create({fileId:documentId, resource: resource}, (error, result)=>{
if (error) return;
//If this work then we know the permission for public share has been created
});
Now we are almost ready, we only need the URL. Gladly the sharable URL has a stable format, so we can compose it by our selves without the need for an extra request:
https://docs.google.com/document/d/${documentId}}/view
Node.js Google Api changes quickly, in case of any confusion, I'm using "googleapis": "^38.0.0",

Categories