Hapi + Boom - Which types I should assign to error? - hapi

I use hapi + boom, but I don't know which types I should add to error.
At the moment my code look likes:
} catch (error: any) {
return Boom.badImplementation(error.message);
}
What types is error? And where I can found information about it?

hello i don't know if this is still relevant
but you can see the doc here: https://hapi.dev/module/boom/api/?v=10.0.1#http-4xx-errors
When you say type, what exactly are you talking about?
if you ask what is the type of the argument of the function
then the type is a String
if not, I invite you to detail your request
I add the following answer maybe it will help you :
for the implementation of Boom.notFound() now you can call the function directly (with HapiJs anyway #hapi/boom)
you can do like this
import { app } from '../../../server';
import { IpingController } from '../types/ping.type';
import { badRequest } from '#hapi/boom';
/**
* controller ping
*/
export const PingController: IpingController = {
/**
* route ping pour tester le server et retourner une valeur
* #param request
* #param h
* #param err
* #return {status: number, message: string}
*/
get: (request, h, err) => {
if (err) {
app.server.log('error', 'Une erreur est survenu');
return badRequest(err);
}
app.server.log('log', 'pin OK');
return { status: 200, message: 'pin OK' };
}
};
badRequest() ou notFound() it's the same
the argument of its functions are a String or the err object

Related

Not able to call start_query method

Not able to call start_query method
I am trying to query cloudwatch Logs with the below code. But I got the below error
TypeError: cloudwatchlogs.startQuery is not a function
It seems the API was not able to find startQuery method.
Kindly help me resolve the issue.
var AWS = require('aws-sdk');
var cloudwatchlogs = new AWS.CloudWatchLogs({apiVersion: '2014-03-28',
region: 'us-west-2'
});
// Set the region
exports.handler = (event,context,callback) => {
console.log("hai");
AWS.config.update({region: 'us-west-2'});
var params = {
endTime: 1553686248, /* required */
logGroupName: '/aws/lambda/tset', /* required */
queryString: 'fields #message| filter #message like /START/| fields strcontains(#message, "$LATEST") as #CONTAINS_ap | stats sum(#CONTAINS_ap) as #sample',
startTime: 1553538648,
limit: 0
};
cloudwatchlogs.startQuery(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
What version of the 'aws-sdk' are you using? StartQuery was added in 2.364.0: https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md#23640

How can I get the data from token

I am trying to get data included in a JWT Token with Angular 6.
I can do the login action, and return the token with Lumen 5.6 - tymondesigns/jwt-auth
But then, when I print it in JS, I get:
iat: 1531073200
iss: "https://api.kz-api.test/auth/login"
jti: "taCmXQoo0jWs4y7t"
nbf: 1531073200
prv: "87e0af1ef9fd15812fdec97153a14e0b047546aa"
sub: 1
I thought I should have the user object in ‘sub’ array as it identifies the subject of the JWT, but I can only find 1….
What’s wrong with my code:
/**
* Authenticate a user and return the token if the provided credentials are correct.
*
* #return mixed
*/
public function authenticate()
{
// Find the user by email
$user = User::where('email', $this->request->input('email'))->first();
if (!$user) {
return response()->json('login.wrong_email', HttpResponse::HTTP_UNAUTHORIZED);
}
$credentials = Input::only('email', 'password');
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json('login.wrong_password', HttpResponse::HTTP_UNAUTHORIZED);
}
return response()->json(compact('token'), HttpResponse::HTTP_ACCEPTED);
}

facebook messenger bot encoding error

I have written sample echo message bot using facebook messenger api and wit.ai actions.
My message from facebook page is received and the proper action function defined using wit api's is also getting called. However
while returning the response, i am getting followin error as -
Oops! An error occurred while forwarding the response to : Error: (#100) Param message[text] must be a UTF-8 encoded string
at fetch.then.then.json (/app/index.js:106:13)
at process._tickCallback (internal/process/next_tick.js:103:7)
Here is the function which is used to return the response -
const fbMessage = (id, text) => {
const body = JSON.stringify({
recipient: { id },
message: { text },
});
const qs = 'access_token=' + encodeURIComponent(FB_PAGE_ACCESS_TOKEN);
return fetch('https://graph.facebook.com/v2.6/me/messages?' + qs, {
method: 'POST',
headers: {'Content-Type': 'application/json; charset=UTF-8'},
body
})
.then(rsp => rsp.json())
.then(json => {
if (json.error && json.error.message) {
throw new Error(json.error.message);`enter code here`
}
return json;
});
};
I have copied this function from the messenger.js file from the documentation since i am just trying the POC.
I checked the values for text and id in this function and verified using console.log statements and those are coming properly.
Can some experts help me to solve this error?
Note - I tried encoding the text using text.toString("utf8"); but it returns the encoding string as [object object] and thats the
response i get from bot. so it doesnt work.
Get the latest code from node-wit, there is a change in facebook id usage,
According to Facebook:
On Tue May 17 format of user and page ids delivered via webhooks will
change from an int to a string to better support default json encoder
in js (that trims long ints). Please make sure your app works with
string ids returned from webhooks as well as with ints.
Still you are getting issue with the api try to add if(event.message && !event.message.is_echo) condition as shown in below code.
// Message handler
app.post('/webhook', (req, res) => {
const data = req.body;
if (data.object === 'page') {
data.entry.forEach(entry => {
entry.messaging.forEach(event => {
if (event.message && !event.message.is_echo) {
const sender = event.sender.id;
const sessionId = findOrCreateSession(sender);
const {text, attachments} = event.message;
if (attachments) {
fbMessage(sender, 'Sorry I can only process text messages for now.')
.catch(console.error);
} else if (text) {
wit.runActions(
sessionId, // the user's current session
text, // the user's message
sessions[sessionId].context // the user's current session state
).then((context) => {
console.log('Waiting for next user messages');
sessions[sessionId].context = context;
})
.catch((err) => {
console.error('Oops! Got an error from Wit: ', err.stack || err);
})
}
} else {
console.log('received event', JSON.stringify(event));
}
});
});
}
res.sendStatus(200);
});
Reference:
no matching user bug
no matching user fix

Loopback Verify User with lb-mandrill-connector: Uncaught AssertionError: template name should be defined

I'm trying to send an email with mandrill through loopback user.verify method but I'm stucked in this error:
Uncaught AssertionError: template name should be defined
Googleing around I found this PR on loopback: https://github.com/strongloop/loopback/pull/1517/files
but it seems that has not been merged as it brake TravisCI tests...
From that PR, I tried this workaround in my code:
let options = {
type: 'email',
port: '80',
to: ac.email,
from: app.get('emailFrom'),
subject: 'Thanks for registering.',
verifyHref: verifyHref,
template: null,
user: ac
};
var template = loopback.template(path.resolve(__dirname, '../../server/views/verify.ejs'));
options.html = template(options);
But it seems that loopback set a default template if no specified, any suggestion?
I'm running on loopback#2.18
The solution here is not to do the user.verify but generate the token and then call user.save and proceed with the call to mandrill.
context.req.app.models.User.generateVerificationToken(user, function (err,token) {
if (err) {
return next(err);
}
user.verificationToken = token;
user.save(function (err) {
if (err) {
next(err);
}
else {
var url = 'http://' + config.host + ':' + config.port + '/api/users/confirm?uid=2&redirect=/&token=' + token;
var mandrill_client = new mandrill.Mandrill('XXXX');
Shouldn't it be
let options = {
type: 'email',
port: '80',
to: ac.email,
from: app.get('emailFrom'),
subject: 'Thanks for registering.',
verifyHref: verifyHref,
template: path.resolve(__dirname, '../../server/views/verify.ejs'),
user: ac
};
user.verify(options, function(err, response) {
if (err) {
next(err);
return;
}
console.log('> verification email sent:', response);
// render the response template
context.res.render('response', {
title: 'Signed up successfully',
content: 'Please check your email and click on the verification link before logging in.',
redirectTo: '/',
redirectToLinkText: 'Log in'
});
});
The loopback method user.verify compiles and renders the ejs template (via loopback.template) and sends the email via the Email datasource. Unfortunately you can't supply a different template engine .. it's hardcoded to ejs. I wanted to use nunjucks so had to override loopback.template to return the render method of nunjucks so that when loopback.template is called from user.verify it works as expected.
I just stumbled accross the issue today. Mandrill provides built-in template functionality where you you provide dynamic templates within your mandrill account and specify variables to populate using the mandrill connector. When template is provided template.name must exist or an assert statement will fail.
This is taken straight from the code:
/**
* Send transactional email with options
*
* Basic options:
*
* {
* from: { name: "evenemento", email: "crew#evenemento.co" },
* to: "hello#evenemento.co",
* subject: "Ho ho",
* text: "Plain text message",
* html: "<b>Html messages</b> put here"
* }
*
* Full list of options are available here:
* https://mandrillapp.com/api/docs/messages.nodejs.html#method=send
*
* if option template is set than message will be send as template:
*
* {
* from: { name: "evenemento", email: "crew#evenemento.co" },
* to: "hello#evenemento.co",
* subject: "Ho ho",
* template: {
* name: "signup-confirm",
* content: {
* name: "NewUser Name",
* accountId: "123456"
* }
* }
* }

spray authenticate directive returns different HTTP status codes

I am trying a basic authentication on post request in spray.io 1.3.2 using authenticate directive. My code looks following:
val route: Route = {
pathPrefix("ato") {
pathPrefix("v1") {
path("orders" / "updateStatus") {
post {
authenticate(BasicAuth(userPasswordAuthenticator _, realm = "bd ato import api")) {
user =>
entity(as[String]) {e =>
complete {
s"Hello $e "
}
}
}
}
}
}
}
}
def userPasswordAuthenticator(userPass: Option[UserPass]): Future[Option[String]] =
Future {
if (userPass.exists(up => up.user == ato_import_v1_usr && up.pass == ato_import_v1_pwd)) Some("ato_v1")
else None
}
This works perfectly fine, authorized Status Ok 200, unauthorized 401. However when the order of directives is changed as follows:
val route: Route = {
pathPrefix("ato") {
pathPrefix("v1") {
authenticate(BasicAuth(userPasswordAuthenticator _, realm = "bd ato import api")) {
user =>
path("orders" / "updateStatus") {
post {
entity(as[String]) {e =>
complete {
s"Hello $e "
}
}
}
}
}
}
}
}
I am getting Status 405, HTTP method not allowed for unauthorized access. I am not sure why that happens. From certain point it make sense, path is not matched because of missing credentials etc.
Could someone please clarify that?
The reason why I wanted to put authorization at v1 level is that I wanted to make every version protected by different password. Is there a way how to achieve that? What is the best practice in chaining directives?
I would like to follow DRY principle.
Thanks