I have a feathersjs API with a messages service. I want to validate the message model with feathers-hooks-validate-joi module.
Here is my messages-hooks.js file:
const validate = require('feathers-hooks-validate-joi');
const schema = require('./messages.validator');
module.exports = {
before: {
create: [validate.form(schema)],
//others method fields
},
after: {...},
error: {...}
};
Here is my messages.validator.js file:
const Joi = require('joi');
const schema = Joi.object().keys({
name: Joi.string().trim().min(2).required(),
text: Joi.string().trim().min(2).required()
});
module.exports = {schema};
When I try to post a message via curl:
curl 'http://localhost:3030/messages/' -H 'Content-Type: application/json' --data-binary '{ "name": "Hello", "text": "World" }'
I receive this error message:
{
"name": "BadRequest",
"message": "Invalid data",
"code": 400,
"className": "bad-request",
"data": {},
"errors": {
"name": "\"name\" is not allowed",
"text": "\"text\" is not allowed"
}
}
Am I missing something? Am I using the feathers hook correctly?
module.exports = {schema};
This should be:
module.exports = schema;
shouldn't it?
Alternatively, your require statement should be changed to:
const {schema } = require('./messages.validator');
Related
I need to pass an array and a map values to terraform workspace using terraform api
tried calling
{
"data": {
"id":"",
"attributes": {
"key":"PREFIXES",
"value":'{a="b"}',
"description":"some description",
"category":"terraform",
"hcl": false,
"sensitive": false
},
"type":"vars"
}
}
and curl call is
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request PATCH \
--data #payload.json \
https://app.terraform.io/api/v2/workspaces/$WORKSPACE_ID/vars/$PREFIXES_ID
end up with error
{"errors":[{"status":"400","title":"JSON body is invalid","detail":"784: unexpected token at '{ \"data\": { \"id\":\"\", \"attributes\": { \"key\":\"PREFIXES\", \"value\":'{a=\"b\"}', \"description\":\"some description\", \"category\":\"terraform\", \"hcl\": false, \"sensitive\": false }, \"type\":\"vars\" } }'"}]}
I tried implementing the same using python. how ever my terraform is giving errors:
Error: Invalid for_each argument
on main.tf line 18, in resource "aws_s3_bucket_object" "obj":
18: for_each = var.prefixes
python3
def update_workspace_vars(workspace_vars, var_values, params):
headers = {"Authorization": "Bearer " + params["TOKEN"],
"Content-Type": "application/vnd.api+json"}
for k in var_values:
payload = {
"data": {
"id": workspace_vars[k],
"attributes": {
"key": k,
"value": var_values[k],
"category": "terraform"
},
"type": "vars"
}
}
patch_params = dict((k, params[k]) for k in ("workspace_id", "tfe_host"))
patch_params.update({"var_id": workspace_vars[k]})
url = "https://{tfe_host}/api/v2/workspaces/{workspace_id}/vars/{var_id}".format(**patch_params)
response = http.request("PATCH", url, headers=headers, body=json.dumps(payload)).data
var_variables = {"prefixes": {"a": ["a1", "a2", "a3"], "b": ["b1", "b2", "b3"]}}
and my terraform code :
resource "aws_s3_bucket" "b" {
bucket = "my-tf-test-bucket-pinnaka"
acl = "private"
}
resource "aws_s3_bucket_object" "obj" {
for_each = var.prefixes
bucket = aws_s3_bucket.b.id
key = each.key
content = each.value
}```
You JSON seems to be invalid.
{
"data": {
"id":"",
"attributes": {
"key":"PREFIXES",
"value":'{a="b"}',
"description":"some description",
"category":"terraform",
"hcl": false,
"sensitive": false
},
"type":"vars"
}
}
"value":'{a="b"}' is invalid JSON syntax.
Either use "value": { "a" : "b"} as JSON or otherwise "value":\"{a=\'b\'}\" escape the single quotes to keep {"a"="b"} from getting parsed as JSON.
I created a local variables names local_prefix and pass var.prefixes to jsoncode.
this worked.
locals{
local_prefix = jsoncode(var.prefix)
}
applied for_each on local_prefix
I'm having a hard time getting Auth0 integration working. I'm getting the response shown below
{
"name": "NotAuthenticated",
"message": "error:0909006C:PEM routines:get_name:no start line",
"code": 401,
"className": "not-authenticated",
"data": {
"library": "PEM routines",
"function": "get_name",
"reason": "no start line",
"code": "ERR_OSSL_PEM_NO_START_LINE"
},
"errors": {}
}
When doing a GET to https://localhost:433/users with headers
{
Authorization: Bearer REMOVED
}
The REMOVED part above was the token returned from calling
curl 'http://localhost:3030/users/' -H 'Content-Type: application/json'
Here is my default.json
{
"host": "localhost",
"port": 433,
"public": "../public/",
"paginate": {
"default": 10,
"max": 50
},
"authentication": {
"entity": "user",
"service": "users",
"secret": "REMOVED",
"authStrategies": [
"jwt",
"local"
],
"jwtOptions": {
"header": {
"typ": "access"
},
"audience": "http://vice-node-boilerplate",
"issuer": "feathers",
"algorithm": "RS256",
"expiresIn": "1d"
},
"local": {
"usernameField": "email",
"passwordField": "password"
},
"oauth": {
"redirect": "/",
"auth0": {
"key": "REMOVED",
"secret": "REMOVED",
"subdomain": "vicesoftware"
}
}
},
"postgres": "postgres://postgres:#localhost:5432/vice_node_boilerplate"
}
I've updated authentication.js as shown below
const { AuthenticationService, JWTStrategy } = require('#feathersjs/authentication');
const { LocalStrategy } = require('#feathersjs/authentication-local');
const { expressOauth, OAuthStrategy } = require('#feathersjs/authentication-oauth');
class Auth0Strategy extends OAuthStrategy {
async getEntityData(profile) {
const baseData = await super.getEntityData(profile);
return {
...baseData,
email: profile.email
};
}
}
module.exports = app => {
const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('auth0', new Auth0Strategy());
app.use('/authentication', authentication);
app.configure(expressOauth());
};
and I've updated index.js as shown below
/* eslint-disable no-console */
const https = require('https');
const fs = require('fs');
const logger = require('./logger');
const app = require('./app');
const port = app.get('port');
const key = fs.readFileSync(__dirname + '/localhost-key.pem');
const cert = fs.readFileSync(__dirname + '/localhost.pem');
if (!key) {
throw Error("Unable to read certificate key file");
}
if (!cert){
throw Error("Unable to read certificate cert key file");
}
const server = https.createServer({
key,
cert
}, app).listen(port);
process.on('unhandledRejection', (reason, p) =>
logger.error('Unhandled Rejection at: Promise ', p, reason)
);
server.on('listening', () =>
logger.info('Feathers application started on http://%s:%d', app.get('host'), port)
);
I generated the local dev cert files localhost-key.pem and localhost.pem following the instructions found here: https://auth0.com/docs/libraries/secure-local-development
Edit 1
Note that I also tried generating a cert using these instructions from node.js docs: https://nodejs.org/en/knowledge/HTTP/servers/how-to-create-a-HTTPS-server/
You changed the jwtOptions.algorithm configuration to RS256. This needs additional configuration, specifically a valid private key. The error indicates that the private key provided is not valid. More information can be found in the node-jsonwebtoken documentation. I recommend to stick with the default HS256/384/512 algorithms if you are not sure.
I have the following JSON payload:
"app": {
"name": "myapp",
"version": "1.0.0",
"last_commit": {
"author_name": "Jon Snow"
"author_email": "my#email.com"
}
}
and the following .js file (using Mocha, Supertest and Should):
var supertest = require('supertest')
var should = require('should')
var server = supertest.agent('http://localhost:3001')
describe('GET /', function () {
it('should respond with JSON', function (done) {
server
.get('/')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
.end(function (err, res) {
var payload = res.body.app;
payload.should.have.property("app");
payload.should.have.property("name");
payload.should.have.property("version");
payload.should.have.property("last_commit");
payload.should.have.property("last_commit.author_name");
payload.should.have.property("last_commit.author_email");
done();
});
});
});
When I test the app, I receive the following error message:
Uncaught AssertionError: expected Object {
"name": "myapp",
"version": "1.0.0",
"last_commit": Object {
"author_name": "Jon Snow"
"author_email": "my#email.com"
}
} to have property 'last_commit.author_name'
Why am I receiving an assertion error on the these lines?
payload.should.have.property("last_commit.author_name");
payload.should.have.property("last_commit.author_email");
Assertion is looking for a property called last_commit.author_name which is not present. You may want to break that into two assertions.
payload.should.have.property("last_commit");
let last_commit = payload.last_commit;
last_commit.have.property("author_name");
I want to experiment with Google Datastore via Apps Script because I have a current solution based on Google sheets that runs into timeout issues inherent in constantly transacting with Drive files. I've created a test project in Google cloud with a service account and enabled library MZx5DzNPsYjVyZaR67xXJQai_d-phDA33
(cGoa) to handle the Oauth2 work. I followed the guide to start it up here and got all the pertinent confirmation that it works with my token (and that removing the token throws an 'authentication failed prompt').
Now I want to start with a basic query to display the one entity I already put in. I can use the API Explorer here and run this query body:
{
"query": {}
}
and get this result:
{
"batch": {
"entityResultType": "FULL",
"entityResults": [
{
"entity": {
"key": {
"partitionId": {
"projectId": "project-id-5200707333336492774"
},
"path": [
{
"kind": "Transaction",
"id": "5629499534213120"
}
]
},
"properties": {
"CommentIn": {
"stringValue": "My First Test Transaction"
},
"Status": {
"stringValue": "Closed"
},
"auditStatus": {
"stringValue": "Logged"
},
"User": {
"stringValue": "John Doe"
},
"Start": {
"timestampValue": "2017-08-17T18:07:04.681Z"
},
"CommentOut": {
"stringValue": "Done for today!"
},
"End": {
"timestampValue": "2017-08-17T20:07:38.058Z"
},
"Period": {
"stringValue": "08/16/2017-08/31/2017"
}
}
},
"cursor": "CkISPGogc35whh9qZWN0LWlkLTUyMDA3MDcwODA1MDY0OTI3NzRyGAsSC1RyYW5zYWN0aW9uGICAgICAgIAKDBgAIAA=",
"version": "1503004124243000"
}
],
"endCursor": "CkISPGogc35wcm9qZWN0LWlkLTUyMDAxxDcwODA1MDY0OTI3NzRyGAsSC1RyYW5zYWN0aW9uGICAgICAgIAKDBgAIAA=",
"moreResults": "NO_MORE_RESULTS"
}
}
I try to do the same thing with this code:
function doGet(e)
{
var goa = cGoa.GoaApp.createGoa('Oauth2-Service-Account',
PropertiesService.getScriptProperties()).execute(e);
if(goa.hasToken()) {var token = goa.getToken();}
var payload = {"query":{}}
;
var result = UrlFetchApp.fetch('https://datastore.googleapis.com/v1/projects/project-id-5200707333336492774:runQuery',
{
method: "POST",
headers: {authorization: "Bearer " + goa.getToken()},
muteHttpExceptions : true,
payload: payload
});
Logger.log(result.getBlob().getDataAsString());
}
and get this error in the logger:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"query\": Cannot bind query parameter. 'query' is a message type. Parameters can only be bound to primitive types.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"query\": Cannot bind query parameter. 'query' is a message type. Parameters can only be bound to primitive types."
}
]
}
]
}
}
If I try to use another word such as 'resource' or 'GqlQuery', I get this error:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"GqlQuery\": Cannot bind query parameter. Field 'GqlQuery' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"GqlQuery\": Cannot bind query parameter. Field 'GqlQuery' could not be found in request message."
}
]
}
]
}
}
I can't tell from the API Documentation what my syntax is supposed to be. Can anyone tell me how to compile a functional request body from Apps Script to Datastore?
You need to set the contentType of your payload as well as stringify your JSON payload as follows:
var result = UrlFetchApp.fetch(
'https://datastore.googleapis.com/v1/projects/project-id-5200707333336492774:runQuery',
{
'method':'post',
'contentType':'application/json',
'headers': {authorization: "Bearer " + goa.getToken()},
'payload':JSON.stringify(payload)
}
);
hi all iam trying insert post using GAS but failed.. can you tell me what im wrong... thx in advance....
here my code
`function sendHttpPost() {
var API_KEY = 'my api key';
var scope = "http://www.blogger.com/feeds/";
var oAuthConfig = UrlFetchApp.addOAuthService("blogger");
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
var payload =
{
"kind": "blogger#post",
"blog": {
"id": "486683248036684073"
},
"title": "A new post",
"content": "With <b>exciting</b> content..."
}
var options =
{
"contentType":"application/json",
"oAuthServiceName" : "blogger",
"oAuthUseToken" : "always",
"method" : "POST",
"payload" : payload
};
var respon = UrlFetchApp.fetch("https://www.googleapis.com/blogger/v3/blogs/486683248036684073/posts?key="+API_KEY, options);
and here is error message
Request failed for returned code 400. Server response: { "error": {
"errors": [ { "domain": "global", "reason": "parseError", "message":
"Parse Error" } ], "code": 400, "message": "Parse Error" } }
I believe you are trying to use oauth1 when oauth2 is required.
there already is a unanswered request about that here.
Implementing oauth 2 with Google app script is really a pain, so I made an attempt to build a library that could answer the need (dioxygen library) - it work a little bit like the oauth2 playground but it's less pretty.
With a little work you should be able to adapt it to your need with blogger.
I tried Harold's library, but after successfully retrieving OAuth token, I ended up with the same error.
But, when I issued the same JSON request as in my script through the API Explorer, it was processed:
https://developers.google.com/blogger/docs/3.0/reference/posts/insert
[UPDATE]
I am taking it back. This code works. I just replaced the payload variable and put the JSON request straight into URL fetch options. So there was some problem with passing that payload variable into options variable.
function testBlogger() {
var payload =
{
"kind": "blogger#post",
"blog": {
"id": "YOUR_BLOG_ID"
},
"title": "New post",
"content": "With content..."
};
var options =
{
"method" : "post",
"headers" : { "Authorization" : "Bearer YOUR_ACTIVE_TOKEN"},
"contentType" : "application/json",
"payload" : '{ "kind": "blogger#post", "blog": { "id": "YOUR_BLOG_ID" }, "title": "New post", "content": "With content..." }'
};
try {
var result = UrlFetchApp.fetch(
"https://www.googleapis.com/blogger/v3/blogs/YOUR_BLOG_ID/posts",
options);
Logger.log(result);
} catch (e) {
Logger.log(e);
}
}