Nodemailer SES TRANSPORT Error: "UnexpectedParameter: Unexpected key 'Destination' found in params" - amazon-ses

Facing issue while sending AWS SES Templated email using SES TRANSPORT from Nodemailer.
In SES TRANSPORT Documentation, it says
To use SES transport, set a aws.SES object as the value for SES property in Nodemailer transport options.
Here's how my code looks.
transporter.sendMail({
ses: {
Destination: {
CcAddresses: [],
ToAddresses: 'recipient#example.com'
},
Source: 'sender#example.com' ,
Template: 'template_name' ,
TemplateData: JSON.stringify(data) ,
// optional extra arguments for SendRawEmail
Tags: [{
Name: 'tag name',
Value: 'tag value'
}]
}
}, (err, info) => {
console.log(info.envelope);
console.log(info.messageId);
});
This is the error I am getting.
2019-08-12T17:03:38.210Z error: There were 3 validation errors:
* UnexpectedParameter: Unexpected key 'Destination' found in params
* UnexpectedParameter: Unexpected key 'Template' found in params
* UnexpectedParameter: Unexpected key 'TemplateData' found in params

Related

SignatureDoesNotMatch.The request signature we calculated does not match the signature you provided. Check your key and signing method

I am trying to implement the auto-update functionality in an electron app using a private s3 bucket. but it giving me a signature mismatch error. Please can anyone help me with this?
I have used the following code structure,
let opts = {
service: 's3',
region: 'us-east-1',
host: 'bucket-name.s3.amazonaws.com',
path: '/latest.yml'
};
console.log(opts);
aws4.sign(opts, {
accessKeyId: 'XXXXXXXXXXXXXXXXXXXX',
secretAccessKey: 'XXXXXXXXXXXXXXXX'
})
console.log(opts.headers);
autoUpdater.requestHeaders = opts.headers;
autoUpdater.checkForUpdates();
autoUpdater.on('checking-for-update', () => {
})
The problem should be the / before latest.yml in your opts. Removing it should work

Files larger than ~7mb throws "Response not received." on IBM Watson Speech-To-Text async createJob call

I'm working on server-side speech to text transcription, and I was able to get a post endpoint working for smaller files, but anything larger than ~7Mb throws an error that doesn't make much sense to me.
I know this code works for small files, and that the callback URL is registered correctly. I've tried throwing the "readableTranscriptStream" creation in a setTimeout() function, just to make sure it wasn't an issue of the full file not being passed to the createJob call. I've also tried just passing req.file.buffer as an argument for the audio param. I also know it isn't an issue of the encoding of the files being incorrect, as I've used the same audio file, slowly increasing the length and size of the file until it threw this error, and it worked until I hit about 7.2Mb, or ~3 min of audio in a .wav 16-bit encoded file.
I've also tried this with the fs.createFileStream('./local_test.wav') as an argument and gotten the same error back, though when I tried that, the _requestBodyLength field in the error was 10485760, and the _requestBodyBuffers was an array of objects. I realize this 10485760 is the same as the maxBodyLength, but the docs for the API say that "You can pass a maximum of 1 GB and a minimum of 100 bytes of audio with a request", and the test audio was, again ~7.2 Mb.
username: process.env.wastonUsername,
password: process.env.watsonPassword,
url: 'https://stream.watsonplatform.net/speech-to-text/api/'
});
const storage = multer.memoryStorage();
const upload = multer({ storage: storage , limit: {fields: 1, fileSize: 209715200, files:1, parts:2}});
upload.single('track')(req,res, (err) => {
req.setTimeout(0);
if (err) {
console.log(err);
return res.status(400).json({ message: err })
}
const registerCallbackParams = {
callback_url: <my_callback_url>,
user_secret: "Test"
};
const readableTranscriptStream = new Readable();
readableTranscriptStream.push(req.file.buffer);
readableTranscriptStream.push(null);
const createJobParams = {
audio: readableTranscriptStream,
callback_url: <my_callback_url>,
content_type: req.file.mimetype,
events:"recognitions.completed_with_results",
inactivity_timeout: -1
};
speechToText.createJob(createJobParams)
.then(recognitionJob => {
console.log(recognitionJob);
})
.catch(err => {
console.log('error:', err);
});
})
The error I'm getting back is :
error:{
Error: Response not received. Body of error is HTTP ClientRequest object
at formatError (/app/node_modules/ibm-cloud-sdk-core/lib/requestwrapper.js:111:17 )
at /app/node_modules/ibm-cloud-sdk-core/lib/requestwrapper.js:259:19 at process._tickCallback (internal/process/next_tick.js:68:7 )
message:'Response not received. Body of error is HTTP ClientRequest object',
body:Writable {
_writableState:WritableState {
objectMode:false,
highWaterMark:16384,
finalCalled:false,
needDrain:false,
ending:false,
ended:false,
finished:false,
destroyed:false,
decodeStrings:true,
defaultEncoding:'utf8',
length:0,
writing:false,
corked:0,
sync:true,
bufferProcessing:false,
onwrite:[
Function:bound onwrite
],
writecb:null,
writelen:0,
bufferedRequest:null,
lastBufferedRequest:null,
pendingcb:0,
prefinished:false,
errorEmitted:false,
emitClose:true,
bufferedRequestCount:0,
corkedRequestsFree:[
Object
]
},
writable:true,
_events:[
Object:null prototype
] {
response:[
Function:handleResponse
],
error:[
Function:handleRequestError
]
},
_eventsCount:2,
_maxListeners:undefined,
_options:{
maxRedirects:21,
maxBodyLength:10485760,
protocol:'https:',
path:'/speech-to-text/api/v1/recognitions?callback_url=<my_callback_url>&events=recognitions.completed_with_results&inactivity_timeout=-1',
method:'post',
headers:[
Object
],
agent:[
Agent
],
auth:undefined,
hostname:'stream.watsonplatform.net',
port:null,
nativeProtocols:[
Object
],
pathname:'/speech-to-text/api/v1/recognitions',
search:'?callback_url=<my_callback_url>&events=recognitions.completed_with_results&inactivity_timeout=-1'
},
_ended:false,
_ending:true,
_redirectCount:0,
_redirects:[
],
_requestBodyLength:0,
_requestBodyBuffers:[
],
_onNativeResponse:[
Function
],
_currentRequest:ClientRequest {
_events:[
Object
],
_eventsCount:6,
_maxListeners:undefined,
output:[
],
outputEncodings:[
],
outputCallbacks:[
],
outputSize:0,
writable:true,
_last:true,
chunkedEncoding:false,
shouldKeepAlive:false,
useChunkedEncodingByDefault:true,
sendDate:false,
_removedConnection:false,
_removedContLen:false,
_removedTE:false,
_contentLength:null,
_hasBody:true,
_trailer:'',
finished:false,
_headerSent:false,
socket:null,
connection:null,
_header:null,
_onPendingData:[
Function:noopPendingOutput
],
agent:[
Agent
],
socketPath:undefined,
timeout:undefined,
method:'POST',
path:'/speech-to-text/api/v1/recognitions?callback_url=<my_callback_url>&events=recognitions.completed_with_results&inactivity_timeout=-1',
_ended:false,
res:null,
aborted:1558070725953,
timeoutCb:null,
upgradeOrConnect:false,
parser:null,
maxHeadersCount:null,
_redirectable:[
Circular
],
[
Symbol(isCorked)
]:false,
[
Symbol(outHeadersKey)
]:[
Object
]
},
_currentUrl:'https://stream.watsonplatform.net/speech-to-text/api/v1/recognitions?callback_url=<my_callback_url>&events=recognitions.completed_with_results&inactivity_timeout=-1'
}
}
Try adding maxContentLength: Infinity as an option when instantiating SpeechToText
const speechToText = new SpeechToTextV1({
username: 'user',
password: 'pass',
version: '2019-01-01',
maxContentLength: Infinity,
});
the limit is 1GB, please make sure you are using Chunked transfer encoding in the submission, that a typical cause of errors when feeding large files. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding

Identifying Mongoose schema validation errors as HTTP status codes

I'm leveraging Keystone.js to provide a lightweight CMS and API. I'm checking for duplicate entries on a List as such:
Registration.schema.post('save', function(error, registration, next) {
if (error && error.name === 'MongoError' && error.code === 11000) {
error = Error(`409|${ registration['email'] } is already registered`);
}
next(error);
});
I'm parsing the status code off the error message to return in my API endpoint.
Is there a different way to provide a friendly error message for duplicates in Keystone admin and be able to return the correct status code for API calls?
as db version v3.6.9
$ mongod --version
db version v3.6.9
git version: 167861a164723168adfaaa866f310cb94010428f
OpenSSL version: OpenSSL 1.0.1t 3 May 2016
allocator: tcmalloc
modules: none
build environment:
distmod: debian81
distarch: x86_64
target_arch: x86_64
I think you should check for ValidationError property instead MongoError as below:
RegistrationSchema.create(obj)
.then(...)
.catch(err => console.error('[registration] output: ', err);
We'll suppose the email is not mentioned before to simulate an is required error.
You'll see like that:
[registration] error: { ValidationError: Registration validation failed: email: Path `email` is required.
at ValidationError.inspect (....)
errors:
{
email:
{ Path `email` is required.
...
message: 'Path `email` is required.',
name: 'ValidatorError',
properties: [Object],
kind: 'required',
path: 'email',
value: [],
reason: undefined,
'$isValidatorError': true } },
_message: 'Registration validation failed',
name: 'ValidationError' }

Using Temporary Credentials giving SignatureDoesNotMatch issue

We are working on s3 browser based multipart file using EvaporateJS, Using pre-signed URL with temperory credentials.
Following will be my configuration
var amz_headers_common = {};
var amz_headers_at_initiate = {};
var amz_headers_at_upload = {};
var amz_headers_at_complete = {};
amz_headers_common['x-amz-acl'] = 'private';
amz_headers_common['x-amz-security-token'] = '<?=AWS_TOKEN;?>';
amz_headers_at_initiate['x-amz-acl'] = 'private';
amz_headers_at_initiate['x-amz-security-token'] = '<?=AWS_TOKEN;?>';
var customAuth = $("#signingMethod")[0].checked;
Evaporate.create({
signerUrl: customAuth ? undefined : '<?=AWS_SIGNER_URL;?>',
aws_key: '<?=AWS_KEY;?>' ,
bucket: '<?=AWS_S3_BUCKET;?>',
cloudfront: false,
computeContentMd5: true,
cryptoMd5Method: function (data) { return AWS.util.crypto.md5(data, 'base64'); },
cryptoHexEncodedHash256: function (data) { return AWS.util.crypto.sha256(data, 'hex'); },
logging: true,
s3Acceleration: true,
signTimeout: 10,
s3FileCacheHoursAgo: 1,
maxConcurrentParts:5,
allowS3ExistenceOptimization: true,
sendCanonicalRequestToSignerUrl: true,
customAuthMethod: customAuth? doNotUseUnsafeJavaScriptV4Signer : undefined,
evaporateChanged: function (file, evaporatingCount) {
$('#totalParts').text(evaporatingCount);
if (evaporatingCount > 0) {
$("#pause-all, #pause-all-force, #cancel-all").show();
} else if (evaporatingCount === 0) {
$("#pause-all, #pause-all-force, #resume, #cancel-all").hide();
}
}
})
var promise = _e_.add({
name: name,
file: files[i],
started: callback_methods.started,
complete: callback_methods.complete,
cancelled: callback_methods.cancelled,
progress: callback_methods.progress,
error: callback_methods.error,
warn: callback_methods.warn,
paused: callback_methods.paused,
pausing: callback_methods.pausing,
resumed: callback_methods.resumed,
nameChanged: callback_methods.nameChanged,
xAmzHeadersCommon: amz_headers_common,
xAmzHeadersAtInitiate: amz_headers_at_initiate,
xAmzHeadersAtUpload: amz_headers_at_upload,
xAmzHeadersAtComplete: amz_headers_at_complete
},
{
bucket: '<?=AWS_S3_BUCKET;?>', // Shows that the bucket can be changed per
aws_key: '<?=AWS_KEY;?>' // Shows that aws_key can be changed per
}
But I'm getting following signature mismatch error.
AWS Code: SignatureDoesNotMatch, Message:The request signature we calculated does not match the signature you provided. Check your key and signing method.status:403
Following will be log
Without temperary credentials following cannonical request and v4 string to sign.
POST
/test-video.mp474.6796611212833
uploads=
host:<bucket-name>.s3-accelerate.amazonaws.com
x-amz-date:20170428T055938Z
host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
V4 stringToSign: AWS4-HMAC-SHA256
20170428T055938Z
20170428/ap-southeast-1/s3/aws4_request
ce2c7c5fbbf58483efbd4bd244551d138353ebb7b7233d3fdce73e85d96fad8d
--------------------------------------------------------------------------------------
Using temperary credentials following cannonical request and v4 string to sign.
initiate V4 CanonicalRequest: POST
/test-video.mp461.80892198840156
uploads=
host:<bucket-name>.s3-accelerate.amazonaws.com
x-amz-acl:private
x-amz-date:20170427T160400Z
x-amz-security-token:FQoDYXdzEDEaDIkS6zY1Oj8PQLLDVSK5A5pPusfWw81Yq3v0c4VqlyyQsBDW+PHosDuDnG8EYc9jlXD1tQwiTKU1E2Nf3aKcYmv/BHYwGwOen9GPStPeVBGbWNBzi1lT+B6xOnDvIXzelnuC6Eddt+jYIrjy9RVIKBN/s80NtVwfjmFK+93iOWJzdl2ruRSzQINZ+UuSmuthudkYLZzKy0pDmCrgIz8YCjXsjhN7FyeSZzXk9qmBDCASygVEFDNbkb/xidH/Yj7P9gYdsxY6YokV/CM8ZpAKmE8Lp+en+xs9rDclexFzCId8QyJaGj0xb205WoeRIHr8RSStvyounCxrmhWP6M/eijWTP/uHIfWVDqBadEPSgVWqcEzrW2iJ+0SGROb+In6BMmkEMaw+9L5M+lkgCfMDm5Fw9Ip8bujcb4okoNjEn6L+L0b1lm3yuqvLkT3oOzL3Sn48n3y0dXsYtt3yAq+C02bnfmgtYVQgv1C9TaMHrvipFADYNJ9U81HxQWlgvuSG5BEgqV59PIzGhwPFHais/GyA+a1bmxkyhzKEw1yq6F6+wQ+VBRskmPlahQd9ZK3wrnqvpQm+H7tD2YLkVVQb+AGKtRVU3mOL3yjgnYjIBQ==
host;x-amz-acl;x-amz-date;x-amz-security-token
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
V4 stringToSign: AWS4-HMAC-SHA256
20170427T160400Z
20170427/ap-southeast-1/s3/aws4_request
e0b18a695b23bc16b6727fd2dc417e445266111ebb4995794287a46304d2cc92
Please help me to solve singature mismatch issue.
Wherever you instantiate your S3 client for the bucket, you'll want to set your signature version to v4, since that's what your temporary credentials are configured for. Something like this:
var s3 = new AWS.S3({
signatureVersion: 'v4'
});

sails-rabbitmq adapter integration with mongodb issue

I have setup a sailsjs project and trying to access rabbitmq using sails-rabbitmq adapter. I have followed https://www.npmjs.com/package/sails-rabbitmq .
I want to use mongodb with rabbitmq. problem is when i 'sails lift' i get this error.
error: A hook (orm) failed to load!
error: Error: One of your models (message) refers to multiple datastores.
Please set its configured datastore to a string instead of an array in its model definition (.connection) or the app-wide default (sails.config.models.connection)
(this is conventionally set in your config/models.js file, or as part of your app's environment-specific config).
at constructError (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\lib\construct-error.js:57:13)
at validateModelDef (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\lib\validate-model-def.js:97:11)
at C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\lib\initialize.js:218:36
at arrayEach (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\lodash\index.js:1289:13)
at Function.<anonymous> (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\lodash\index.js:3345:13)
at Array.async.auto._normalizeModelDefs (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\lib\initialize.js:216:11)
at listener (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\node_modules\async\lib\async.js:605:42)
at C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\node_modules\async\lib\async.js:544:17
at _arrayEach (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\node_modules\async\lib\async.js:85:13)
at Immediate.taskComplete (C:\Users\demoapp\AppData\Roaming\npm\node_modules\sails\node_modules\sails-hook-orm\node_modules\async\lib\async.js:543:13)
at processImmediate [as _immediateCallback] (timers.js:383:17)
I have > connection: [ 'rabbitCluster', 'regularMongo' ]
in my Message model. regularMongo is mongodb connection. Please let me know what other configuration i am missing.
With following config I do not see any error. In sails.config.models set
module.exports.models = {
connection: 'someMongodbServer',
migrate: 'safe'
};
in Message.js set
module.exports = {
connection: [ 'rabbitCluster', 'someMongodbServer' ],
routingKey: [ 'parentMessage' ],
attributes: {
title: 'string',
body: 'string',
parentMessage: {
model: 'message'
}
}
};