I'm using the node.js SDK to access the Vimeo API. I'm attempting to batch edit my albums (Showcases) descriptors and names. I've already created my Vimeo API app and enabled the "Edit" access. Sadly, when I run the code, it returns an error telling me that my access token does not have "edit"\ scope. Below is the code snippet I'm using to send the request:
async function setDescriptors(albumPath, newTitle, description) {
const vimeo = await ensureVimeoClient();//Checks the connection before proceeding
console.log("Album path: " + albumPath + "\n" + description);
return await vimeo.request({
method: 'PATCH',
path: albumPath,
params: {
'name': newTitle,
'description': description
}
}, function (error, body, statusCode, headers) {
if (error) {
console.log('There was an error making the request.')
console.log('Server reported: ' + error)
return
}
})
}
Any thoughts on why I'm getting the error? Below is the exact message:
Server reported: Error: {"error":"Your access token does not have the "edit" scope"}
On the developer site where you generate your access token (https://developer.vimeo.com/apps), you need to generate an authenticated access token with 'public', 'private', and 'edit' scopes.
Related
I would want to get the ID token to be consumed in google appscript web app (which needs my account) in order to access the API.
My end goal is to know how can I achieve getGoogleIDTokenToInvokeAppScriptEndPoint (I have added in my sample code).
What exactly needs to be done to programatically access ID Token to invoke AppScript APIs from external service.
I am not sure how to generate the same programatically. Do I need to create a service account on my behalf?
Lets say I created a google account as abc#gmail.com, so I need to access the service account programatically for this user only and not some other service account. I then want to get the ID token and invoke my appscript services using the same.
Here's what I have already done:
Created my doPost request and deployed it like this:
Now the URL that I get can only be invoked if it has a bearer ${token}, where token is my ID token.
My question is how to possibly get this ID token programatically from an external service? I am using Node Application and I would like something like:
// External Script from where I am invoking AppScript API
const token = getGoogleIDTokenToInvokeAppScriptEndPoint();
// Now Since I got my ID Token, I could use the same
// to invoke my appScript app:
fetch(appScriptEndpoint,
{
method:"POST",
headers: {
Authorization: `Bearer ${token}` // Token I got from first step
}
}).then(res => res.json().then(data => data))
Here's how my appscript looks like (though not much relevant here, but still adding for detailing):
// AppScript Script
const doPost = (request = {}) => {
const { _, postData: { contents, type } = {} } = request;
let query = {};
if (type === 'application/json') {
query = JSON.parse(contents);
} else if (type === 'application/x-www-form-urlencoded') {
contents
.split('&')
.map((input) => input.split('='))
.forEach(([key, value]) => {
query[decodeURIComponent(key)] = decodeURIComponent(value);
});
} else if (type === 'text/plain') {
try {
query = JSON.parse(contents);
} catch (e) {
return ContentService.createTextOutput(
JSON.stringify({
error: true,
statusCode: 400,
msg: 'Unable to Parse JSON',
type: type,
requestBody: contents,
payload: {}
})
).setMimeType(ContentService.MimeType.JSON);
}
} else
return ContentService.createTextOutput(
JSON.stringify({
error: true,
statusCode: 400,
msg: 'Unknown Request Type',
type: type,
requestBody: contents,
payload: {}
})
).setMimeType(ContentService.MimeType.JSON);
const apiKey = query.apiKey;
const isAuthenticated = authenticate({apiKey});
if(!isAuthenticated) return ContentService.createTextOutput(
JSON.stringify({
error: true,
statusCode: 401,
msg: 'User not authorized to make the Request.',
type: type,
requestBody: contents,
payload: {}
})
).setMimeType(ContentService.MimeType.JSON);
else {
const {opType,opProps} = query;
const result = requestHandler({opType, opProps});
return ContentService.createTextOutput(
JSON.stringify({
error: false,
statusCode: 200,
msg: 'Connection Established',
type: type,
requestBody: contents,
payload: result
})
).setMimeType(ContentService.MimeType.JSON);
}
};
Please note that I already know how to invoke it by keeping my web app open however, I want to invoke it when authentication is required as shown in the above configuration.
I'm using Stripe, and trying to send a test webhook to my URL and database hosted by Firebase. When I "send test webhook," I get the following error message in the Stripe Console:
Test Webhook Error: 405
"append .json to your request URI to use the rest API"
My code is a direct copy of the tutorial: https://github.com/GaryH21/Stripe-Webhooks-Tutorial/blob/master/functions/index.js
Here is the code of my index.js:
const functions = require('firebase-functions');
const stripe = require("stripe")(functions.config().keys.webhooks);
const admin = require('firebase-admin')
admin.initializeApp();
const endpointSecret = functions.config().keys.signing;
exports.events = functions.https.onRequest((request, response) => {
let sig = request.headers["stripe-signature"];
try {
let event = stripe.webhooks.constructEvent(request.rawBody, sig, endpointSecret)
return admin.database().ref('/events').push(event)
.then((snapshot) => {
return response.json({ received: true, ref: snapshot.ref.toString() })
})
.catch((err) => {
console.error(err)
return response.status(500).end() // error saving to database
})
} catch (err) {
return response.status(400).end() // signing signature failed
}
})
exports.exampleDataBaseTrigger = functions.database.ref('/events/{eventId}').onCreate((snapshot, context) => {
return console.log({
eventId: context.params.eventid,
data: snapshot.val()
})
})
The only time in the tutorial and in my code that .json is used is in the line: return response.json({ received: true, ref: snapshot.ref.toString() })
Should I be appending .json onto "request" somewhere, such as in request.RawBody?
It isn't a problem with the signing keys, as that would give the 400 Error message, which I already dealt with and fixed.
I would be happy to share the code of other files in my app, but as far as I can tell none of the rest is relevant to the problem. Thank you very much.
I'm trying to establish a real-time socket connection to my client
side via feathers channels. It works without any sort of
authentication. But if i add the following login action scoket is
throwing a weak map key error.
app.on('login', (authResult, { connection }) => {
console.log(connection) // returns undefined
....
})
This is the error I'm receiving
Unhandled Rejection at: Promise Promise { TypeError:
Invalid value used as weak map key
at WeakMap.set ()
app.on('login', (authResult, { connection }) => {
console.log("============>>", connection)
if (authResult && connection) {
app.channel('anonymous').leave(connection);
if (authResult.user && authResult.user['chanelName']) {
let channelName = authResult.user['chanelName'].toString();
channelName = channelName.substr(0, 5)
app.channel(`channel/${channelName}`).join(connection);
} else
app.channel('authenticated').join(connection)
}
});
The connection object is undefined, i think that causes the problem.
Anu suggestions?
Please provide the client side script.
According to fethers documentation connection can be undefined if there is no real-time connection, e.g. when logging in via REST.
You should authenticate your client.
Sample script
const feathers = require('#feathersjs/feathers');
const socketio = require('#feathersjs/socketio-client');
const io = require('socket.io-client');
const auth = require('#feathersjs/authentication-client');
const socket = io('http://localhost:3031');
const app = feathers();
// Setup the transport (Rest, Socket, etc.) here
app.configure(socketio(socket));
const options = {
header: 'Authorization', // the default authorization header for REST
prefix: '', // if set will add a prefix to the header value. for example if prefix was 'JWT' then the header would be 'Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOi...'
path: '/authentication', // the server-side authentication service path
jwtStrategy: 'jwt', // the name of the JWT authentication strategy
entity: 'user', // the entity you are authenticating (ie. a users)
service: 'users', // the service to look up the entity
cookie: 'feathers-jwt', // the name of the cookie to parse the JWT from when cookies are enabled server side
storageKey: 'feathers-jwt', // the key to store the accessToken in localstorage or AsyncStorage on React Native
storage: undefined // Passing a WebStorage-compatible object to enable automatic storage on the client.
}
app.configure(auth(options))
app.authenticate({
strategy: 'jwt',
accessToken: '<JWT TOKEN>'
}).then(() => {
console.log("Auth successfull")
const deviceService = app.service('myService');
deviceService.on('created', message => console.log('Created a message', message));
}).catch(e => {
console.error('Authentication error', e);
// Show login page
});
Hope this will help you.
I'm building an api with nodejs to interact with both the client(android) and the admin(web).
When the api is started, it works fine for the admin and the views are rendered properly but when I connect the client to the api, I get an error/warning in server console like:
App at port 4003
db connection opened successfully
Categroies Count: 2
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:494:11)
at ServerResponse.setHeader (_http_outgoing.js:501:3)
at ServerResponse.header
(E:\nodeCMSApp\node_modules\express\lib\response.js:767:10)
at ServerResponse.json
(E:\nodeCMSApp\node_modules\express\lib\response.js:264:10)
at Categories.find.select.exec.then.data
(E:\nodeCMSApp\routes\admin_categories.js:20:22)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
(node:13880) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 1): Error: Can't set headers after they are
sent.
(node:13880) [DEP0018] DeprecationWarning: Unhandled promise rejections
are deprecated. In the future, promise rejections that are not handled
will terminate the Node.js process with
a non-zero exit code.
Here's my api code snippet:
router.get('/', (req, res) => {
Categories.find({})
.select('title slug image _id')
.exec()
.then(data => {
if (data) {
res.status(200)
.json({
success: true,
count: data.length,
categories: data
})
// I understand that the problem lies here
res.render('admin/all_categories', {
categories: data
});
} else {
res.render('all_categories', {
categories: null
});
}
})
.catch(error => {
console.error(error);
res.send('Error 404');
});
});
I understand that it's because I have already rendered a view with the response object and I'm calling it again to return some json for the client.
My question is how do I render the view and return json data for the client concurrently withoutany errors?
Thanks.
In your code, you are sending two responses to user if all goes well:
if (data) {
res.status(200).json({
success: true,
count: data.length,
categories: data
});
// I understand that the problem lies here
res.render('admin/all_categories', {
categories: data
});
}
In the moment you perform some call to res.json, res.send, res.redirect, res.render, etc, you are sending the proper headers to user (browser) so, in your case, after res.status(200).json you are trying to send res.render and is not possible because first res.json started sending the result to the user. I guess you want to render all_categories with "data" so you should render the template in backend (compile) before send it to the user.
I am working on an Express App with MongoDB and trying to utilize FeathersJS for all my services. Here I'm running a test try to get an error message from the server to the client, but I have an issue with the response from the error handler. My req headers have the correct application/json stuff, so I assumed the Error Handler should send valid json back.
I know I'm not using the next callback in my function, but when I try to do that it gives the same error, so I'm thinking it has to do with the Error Handler. Any direction here would be greatly appreciated!
The first error log is on the server, which is correct.
Bucket Services
error >>>>> Bucket validation failed
Possibly Unhandled Rejection: Bucket validation failed, Promise { <rejected> 'Bucket validation failed' }
>>>>>> Error: Unexpected token < in JSON at position 0
at convert (/Users/jaruesink/Documents/Projects/Buckets/node_modules/feathers-rest/node_modules/feathers-errors/lib/index.js:365:79)
at toError (/Users/jaruesink/Documents/Projects/Buckets/node_modules/feathers-rest/lib/client/base.js:24:37)
at process._tickCallback (internal/process/next_tick.js:103:7)
my create function within the BucketService class:
create({
amount,
isFund = false,
name,
type,
userID: owner
}, params, next) {
const new_bucket = new Bucket({ name, amount, type, isFund, owner });
return new_bucket.save((error) => {
console.log('error >>>>>', error.message);
if (error) { return Promise.reject(error.message); }
return Promise.resolve(new_bucket);
});
}
my router file:
const feathers = require('feathers');
const errorHandler = require('feathers-errors/handler');
const rest = require('feathers-rest');
const router = feathers();
const LoginService = require('../services/login_service');
const UserService = require('../services/user_service');
const BucketService = require('../services/bucket_service');
// Enable REST services
router.configure(rest());
router.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
router.use('/login', new LoginService());
router.use('/user', new UserService());
router.use('/bucket', new BucketService());
// Set up error handling
router.use(errorHandler());
module.exports = router;
I figured it out, the key was to correctly pass through a callback (next) function as the third parameter to handle errors. FeathersJS handles the Promise Rejections for you on errors. Then in my test I needed to convert the Feathers-Error to JSON before I could get the message.
I changed my test to:
it('can validate an incorrect bucket', (done) => {
const invalid_bucket = {
name: 'Invalid Bucket',
};
bucket_service.create(invalid_bucket, {}, (error) => {
error = error.toJSON();
assert(error.message.length > 0);
done();
});
});
and my create function to:
create({
amount,
isFund = false,
name,
type,
userID: owner
}, params, next) {
const new_bucket = new Bucket({ name, amount, type, isFund, owner });
return new_bucket.save()
.then(created_bucket => Promise.resolve(created_bucket))
.catch(next);
}