Google Storage REST get with axios - rest

I want to get a list of images in a bucket using REST and axios.
ref: https://cloud.google.com/storage/docs/listing-objects#list-objects-json
The documentation gives this curl request
curl -X GET -H "Authorization: Bearer OAUTH2_TOKEN" \
"https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o"
reqConfig: this is a token I use in my REST firestore queries to authenticate the user. I'm using that same token for here. I'm guessing it's the problem but not sure how to fix it.
My result is consistently 404 for a bucket path that I know exists, using the URL from their docs. I should be getting a json list of the files in the bucket.
Error: Request failed with status code 404
Where am I going wrong?
export async function getCompanyStorage(context, apikey, companyId) {
const url = `https://storage.googleapis.com/storage/v1/b/uploads/${companyId}/o?key=${apikey}`;
const cookies = nookies.get(context);
const reqConfig = {
headers: new Headers({
Authorization: "Bearer " + cookies.token,
"Content-Type": "application/json",
}),
};
const result = axios
.get(url, { headers: { Authorization: `Bearer ${reqConfig}` } })
.then((res) => {
return res.data;
})
.catch((error) => {
console.error("error using axios", error);
});
}
Edit: a path to a bucket in the firebase console looks like this
gs://projectname.appspot.com/uploads/WhmDZyQdLVk7n0qR7aTg

I suggest reviewing the documentation you linked to. In particular:
OAUTH2_TOKEN is the access token you generated in Step 1.
BUCKET_NAME is the name of the bucket whose objects you want to list. For example, my-bucket.
You can use a prefix=PREFIX query string parameter to limit results to
objects that have the specified prefix.
Your URL does not contain the name of the bucket as required by the URL pattern. Use the unique name of the bucket where you see "BUCKET_NAME". It looks like, given your example, that it would be "projectname.appspot.com". BUCKET_NAME is not the path of the object within that bucket. If you want to list files under the "uploads" prefix, then you would use the prefix query string parameter to specify that, as documented in the last line of the quoted text.

You can use this function to create Get request with axios for Google Cloud Storage
export const UploadVideo = async (form_data, file, signedurl, asset_uuid) => {
let resultState = { state: '', data: {} };
console.log(signedurl)
/*
const xhr = new XMLHttpRequest();
xhr.open("PUT", signedurl);
xhr.setRequestHeader('Content-Type', "application/octet-stream");
xhr.send(file);
*/
let config = {
headers: {
'Content-Type': 'application/octet-stream',
},
};
await axios.get(signedurl, file, config).then(function (response) {
resultState.state = 'success';
}).catch(function (error) {
resultState.state = 'error';
resultState.data.message = error.message;
window.toastr.error(error.message);
console.log(error)
})
return resultState;
}

Related

CORS error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response

I'm trying to fetch an image resource that's part of a conversation message.
I've tried both FETCH as well as using AXIOS but I'm getting the same error message.
Here's an example of my FETCH request
const token = `${accountSid}:${authToken}`;
const encodedToken = Buffer.from(token).toString('base64');
let response = await fetch('https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
{
method:'GET',
headers: {
'Authorization': `Basic ${encodedToken}`,
}
});
let data = await response.json();
console.log(data);
And here's what Axios looked like
let config = {
method: 'get',
crossdomain: true,
url: 'https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
headers: {
'Authorization': `Basic ${encodedToken}`,
},
};
try {
const media = await axios(config);
console.dir(media);
} catch(err) {
console.error(err);
}
Both ways are NOT working.
After looking into it more, I found out that Chrome makes a pre-flight request and as part of that requests the allowed headers from the server.
The response that came back was this
as you can see, in the "Response Headers" I don't see the Access-Control-Allow-Headers which should have been set to Authorization
What am I missing here?
I have made sure that my id/password as well as the URL i'm using are fine. In fact, I've ran this request through POSTMAN on my local machine and that returned the results just fine. The issue is ONLY happening when I do it in my code and run it in the browser.
I figured it out.
I don't have to make an http call to get the URL. It can be retrieved by simply
media.getContentTemporaryUrl();

Firebase hosting file upload via REST with Apps Script

I want to upload a file to Firebase hosting file upload via REST with Apps Script. Been trying to find a solution for days to no avail :( would highly appreciate any recommendations.
I'm following the official documentation here:
https://firebase.google.com/docs/reference/hosting/rest/v1beta1/sites.versions/populateFiles
And I can successfully get the upload URL using this code:
function getUploadURL() {
const YOUR_PROJECT_ID = 'sites/url-shortener-e42ec/versions/dd393a80797d713d';
let postUrl = 'https://firebasehosting.googleapis.com/v1beta1/YOUR_PROJECT_ID:populateFiles';
postUrl = postUrl.replace('YOUR_PROJECT_ID', YOUR_PROJECT_ID);
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
},
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(postUrl, options);
Logger.log(response);
}
which returns the following:
{
"uploadUrl": "https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files"
}
And this is where I get kinda lost because I'm not quite sure on what to do next. The documentation says:
map (key: string, value: string)
A set of file paths to the hashes corresponding to assets that should be added to the version.
A file path to an empty hash will remove the path from the version.
Calculate a hash by Gzipping the file then taking the SHA256 hash of the newly compressed file.
But if I add a payload with a file hash to the call like so:
{
"files": {
"/teste": "3f0749957a1c4d91ed18b8e9df122709974e4e9c94c57f9245794c21dd76d4bd"
}
}
...then I get the error:
{
"error": {
"code": 400,
"message": "Precondition check failed.",
"status": "FAILED_PRECONDITION"
}
}
PART 2 :
The next issue I found is, now that I have the upload URL, I will need to actually upload the file, and according to their documentation I should:
Perform a multipart POST of the Gzipped file contents to the URL using a forward slash and the hash of the file appended to the end.
which I tried with the following apps script code:
function convert(hash) {
return hash.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
}
function postFile() {
var files = DriveApp.getFilesByName('abc.txt');
let gzip;
let hash;
if (files.hasNext()) {
var file = files.next();
gzip = Utilities.gzip(file.getBlob());
hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzip.getBytes());
}
let postUrl = 'https://upload-firebasehosting.googleapis.com/upload/sites/url-shortener-e42ec/versions/dd393a80797d713d/files/' + convert(hash);
/*
var textBlob = Utilities.newBlob("abc");
const gzip = Utilities.gzip(textBlob);
const hash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, gzipFile.getBytes());
*/
const data = {
"files": {
"/test.txt": convert(hash)
}
};
const options = {
method: 'post',
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`,
accept: 'application/json',
contentType: 'application/json'
},
muteHttpExceptions: true,
payload: JSON.stringify(data)
};
const response = UrlFetchApp.fetch(postUrl, options);
Logger.log(response);
}
... and get the following error:
Couldn't process request (status=412): File url-shortener-e42ec/dd393a80797d713d/0b3b82379e00a1994a46452e8cfd8b2c43ee8599f169a9ee4176253f1a8de469 can't be uploaded.
Appreciate all the help I can get. Thanks in advance!

Flutter qraphQl issue with setting requesting data from body of api

I am trying to connect to an graphQl api that uses the token as the password in the Basic auth section of the header. I have tried using flutter_graphql but as I only get the token back after the user logs in. I have managed to get logged in using:
String username = "";
String password = token;
String basicAuth = 'Basic' + base64Encode(utf8.encode("$username:$password"));
String projects = "query Projects{Projects{id name}}";
Uri newUri = Uri.parse("$link");
var newResponse = await http.post(newUri, headers: {
"Authorization": basicAuth,
"Content-Type": "application/graphql"
}, body: //I need to get projects here.
);
var newNonJsonData = newResponse.body;
group("Testing the graph ql data after logging in: ", () {
test("Logged in", () {
expect(newResponse.statusCode, 200);
});
test("getting the data from the api", () {
print("non json return:" + newNonJsonData);
});
});
I have tried to set the body as
jsonEncode({
'query' : prjects
})
but the moment I request the data it asks to log in.
Please could someone help!!!

GraphQL query to GitHub failing with HTTP 422 Unprocessable Entity

I am currently working on a simple GitHub GraphQL client in NodeJS.
Given that GitHub GraphQL API is accessible only with an access token, I set up an OAuth2 request to grab the access token and then tried to fire a simple GraphQL query.
OAuth2 flow gives me the token, but when I send the query, I get HTTP 422.
Here below simplified snippets from my own code:
Prepare the URL to display on UI side, to let user click it and perform login with GitHub
getGitHubAuthenticationURL(): string {
const searchParams = new URLSearchParams({
client_id,
state,
login,
scope,
});
return `https://github.com/login/oauth/authorize?${searchParams}`;
}
My ExpressJs server listening to GitHub OAuth2 responses
httpServer.get("/from-github/oauth-callback", async (req, res) => {
const {
query: { code, state },
} = req;
const accessToken = await requestGitHubAccessToken(code as string);
[...]
});
Requesting access token
async requestToken(code: string): Promise<string> {
const { data } = await axios.post(
"https://github.com/login/oauth/access_token",
{
client_id,
client_secret,
code
},
{
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
}
);
return data.access_token;
}
Firing simple graphql query
const data = await axios.post(
"https://graphql.github.com/graphql/proxy",
{ query: "{ viewer { login } }"},
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
}
);
Do you guys have any clue?
Perhaps I am doing something wrong with the OAuth2 flow? As in most of the examples I found on the web, a personal token is used for this purpose, generated on GitHub, but I would like to use OAuth2 instead.
Thanks in advance for any help, I really appreciate it!
EDIT
I changed the query from { query: "query { viewer { login } }"} to { query: "{ viewer { login } }"}, nonetheless, the issue is still present.
I finally found the solution:
Change the URL from https://graphql.github.com/graphql/proxy to https://api.github.com/graphql, see here
Add the following HTTP headers
"Content-Type": "application/json"
"Content-Length"
"User-Agent"
Hope this will help others out there.

Error when trying to authorize Axios get request

I am trying to access the Uber API with Axios and I am running into some trouble. I have plugged this data into Postman and I get a 200 response code with no problems. However, when I try to make an Axios call, I get response code 401 unauthorized. Can I get some help looking through my code to find out why my authorization is not working correctly with Axios?
Here is a link to the Uber API docs I am referencing. Uber API Reference
getRide_Uber = async (addressOrigin, addressDestination) => {
let origin = await geocodeAddress(addressOrigin);
let destination = await geocodeAddress(addressDestination);
const url = "https://api.uber.com/v1.2/estimates/price";
const params = {
params: {
start_latitude: origin.lat,
start_longitude: origin.lon,
end_latitude: destination.lat,
end_longitude: destination.lon
}
};
const headers = {
headers: {
Authorization: `Token ${process.env.UBER_SERVER_TOKEN}`
}
};
const response = await axios
.get(url, params, headers)
.then(function(response) {
data = response.data;
})
.catch(function(error) {
console.log(error);
});
return data;
};
Please let me know if anything needs clarification. Thanks!
try below syntax,
const config = {
headers: {
Authorization: `Token ${process.env.UBER_SERVER_TOKEN}`
}
params: {
start_latitude: origin.lat,
start_longitude: origin.lon,
end_latitude: destination.lat,
end_longitude: destination.lon
}
};
const response = await axios
.get(url, config)
.then(function(response) {
data = response.data;
})
.catch(function(error) {
console.log(error);
});
return data;
There is one more aspect axios, async/await is not supported in Internet Explorer and older browsers. So also please check your browser versions as well.
Not sure how are you getting token from env but seems the server token is not getting pass correctly, may be few extra characters while reading from env. Try to run the program first with hard coded token in program itself and once you are sure its not code issue, you can move it into config/env and then debug env read issue.