Sails swagger api documentation - node.js

I am using sails in my node js application. And want to implement swagger api documentation. And I follow Swagger Sails JS document. I got the result from my api doc. And my expected result from api doc . I have write the route in router.js file like below
'post /login': {
controller: 'user/UserController',
action: 'login',
skipAssets: 'true',
//swagger path object
"get": {
"tags": [
"Users"
],
"description": "Get a login user data",
"parameters": [{
"email": "abc#gmail.com",
"password": "12345678y",
"deviceToken": "12345678y",
"deviceType": 2
}],
"responses": {
"200": {
"statusCode": 0,
"status": true,
"message": "string",
"result": {}
}
}
}
}
If I had write wrong in my routes. Then how to write the routes, so that I will get my expected result from api docs?
Thanks!

You can try using this.
And I suppose router file should be like this:
'post /login': {
controller: 'user/UserController',
action: 'login',
skipAssets: 'true',
swagger: {
methods: ["get"],
tags: ["Users"],
description: "Get a login user data",
parameters: [{
email: "abc#gmail.com",
password: "12345678y",
deviceToken: "12345678y",
deviceType: 2
}],
responses: {
'200': {
statusCode: 0,
status: true,
message: "string",
result: {}
}
}
}
}

Related

Stripe create-checkout-session -method returns http 400 (bad request) in production not in localhost

I have been struggling with Stripe http 400 error in production server. The node.js (Express) code below works perfectly with localhost: it connects stripe-service and gets the payment session-id. But the same code in production server (iisnode.exe) returns all the time just http 400 error. My frontend cart-code (Angular) is in different domain than the backend-api where the endpoint below locates. Can anyone figure out what is wrong? Stripe docs for errors (https://stripe.com/docs/api/errors) mention that http 400 often is due to a missing required parameter. But I cannot see that in my case.
app.post('/create-checkout-session', async (req, res) => {
const cartData = req.body
try {
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card', 'sepa_debit'],
shipping_rates: ['shr_1Jmh85AuqIBxGbL5Z7JbTJaV'],
shipping_address_collection: {
allowed_countries: ['FI'],
},
line_items: [{
"price_data": {
"currency": "eur",
"product_data": {
"name": "Product 1",
"description": "Further info here"
},
"unit_amount": 6800
},
"quantity": 2
}],
phone_number_collection: {
enabled: true,
},
mode: 'payment',
success_url: `${stripeUrl}/myynti/success?true&session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${stripeUrl}/myynti/cancel`
});
res.json({ id: session.id });
} catch (e) {
res.status(400);
return res.send({
error: {
message: e.message,
}
});
}
}));
(ADDED after comment by alex)
Here is what I have in Stripe Dashboard behind the url alex provided:
POST /v1/checkout/sessions
Status 400 ERR
ID req_so02k9kRthmCZ7
Time 10/21/21, 5:20:23 PM
IP address ********
API version 2020-08-27 Latest
Source Stripe/v1 NodeBindings/8.178.0
Idempotency Key — 461bb3f4-e2e1-421d-b177-9713176448af
ACTUAL ERROR MESSAGE:
invalid_request_error
The line_items parameter is required in payment mode.
{
"payment_method_types": {
"0": "card",
"1": "sepa_debit"
},
"shipping_rates": {
"0": "shr_1Jmh85AuqIBxGbL5Z7JbTJaV"
},
"shipping_address_collection": {
"allowed_countries": {
"0": "FI"
}
},
"phone_number_collection": {
"enabled": "true"
},
"mode": "payment",
"success_url": "http://localhost:4200/myynti/success?true&session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "http://localhost:4200/myynti/cancel"
}
The error message says that the "line_items parameter" is lacking but that should not be the case? - any ideas why see also my original code where there is line_items parameter included.

Swagger Nest.js ValidationPipe ApiBadRequestResponse

👋I just started playing around with Swagger and everything is amazing. I was able to document all API in an hour or so but I got stuck solving one last issue.
How can I tell swagger to show ApiBadRequestResponse in the format below?
#ApiOkResponse({
type: User,
})
#ApiBadRequestResponse({
type: {
error: String,
message: ValidationError[]
}
})
#Post('/signup')
signUp(
#Body(ValidationPipe) authCredentialsDto: CredentialsDTO
): Promise<User> {
return this.userService.signUp(authCredentialsDto)
}
From what I understand swagger doesn't know how to work with interfaces instead I have to use classes. Is there a simple way to document bad request response triggered by ValidationPipe. This is all native #nestjs behavior so I would assume there must be an easy solution.
This is what gets actually returned from API:
"statusCode": 400,
"error": "Bad Request",
"message": [
{
"target": {
"username": "somename",
"password": "****"
},
"value": "****",
"property": "password",
"children": [], // ValidationError[]
"constraints": {
"matches": "password too weak"
}
}
]

Sequelize - get proper path while validating associations of a model

I'm using Sequelize as an ORM for my project. I have this structure:
const Event = sequelize.define('event', {
// fields defined
});
const Question = sequelize.define('question', {
description: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: '',
validate: {
notEmpty: { msg: 'Description should be set.' }
},
},
// other fields defined
});
Event.hasMany(Question);
Question.belongsTo(Event);
Then I create an instance of the Event model, with associate, like that:
const body = {
questions: [
{ description: '' } // is obviously invalid
],
// some other fields
}
const newEvent = await Event.create(body, {
include: [ Question ]
});
If I have validation errors for the Event instance itself, it returns SequelizeValidationError where I can see the path attribute for each ValidationErrorItem. However, when I have the validation error on a child model, the path attribute for this validation error is unclear:
{
"message": "Description should be set.",
"type": "Validation error",
"path": "description",
"value": "",
"origin": "FUNCTION",
"instance": {
"required": true,
"id": null,
"description": "",
"event_id": 60,
"updated_at": "2018-06-11T12:25:04.666Z",
"created_at": "2018-06-11T12:25:04.666Z"
},
"validatorKey": "notEmpty",
"validatorName": "notEmpty",
"validatorArgs": [
{
"msg": "Description should be set."
}
],
"__raw": {
"validatorName": "notEmpty",
"validatorArgs": [
{
"msg": "Description should be set."
}
]
}
The problem is, it's unclear what caused this error and which child is invalid. When I've used Mongoose as an ORM, if I'd do the same, the path attribute would be equal to something like questions.0.description, and that is way more clear, that way you can see which child is invalid.
So, my question is: is there a way to set up the path attribute while validating the child models?
Apparently it's not presented yet, I've filed an issue on Sequelize repo, here it is: https://github.com/sequelize/sequelize/issues/9524

Atlassian Connect-Express: JIRA REST API authentication within the JIRA plugin

i am using the atlassian-connect-express toolkit for creating Atlassian Connect based Add-ons with Node.js.
It provides Automatic JWT authentication of inbound requests as well as JWT signing for outbound requests back to the host.
The add-on is authenticated when i install it in the JIRA dashboard and return the following pay-load:
{ key: 'my-add-on',
clientKey: '*****',
publicKey: '********'
sharedSecret: '*****'
serverVersion: '100082',
pluginsVersion: '1.3.491',
baseUrl: 'https://myaccount.atlassian.net',
productType: 'jira',
description: 'Atlassian JIRA at https://myaccount.atlassian.net ',
eventType: 'installed' }
But i am not able to authenticate the JIRA Rest Api with the JWT token generated by the framework. It throws below error message.
404 '{"errorMessages":["Issue does not exist or you do not have permission to see it."],"errors":{}}'
below is the code when i send a GET request:
app.get('/getissue', addon.authenticate(), function(req, res){
var request = require('request');
request({
url: 'https://myaccount.atlassian.net/rest/api/2/issue/ABC-1',
method: 'GET',
}, function(error, response, body){
if(error){
console.log("error!");
}else{
console.log(response.statusCode, body);
}
});
res.render('getissue');
});
Below is the code for my app descriptor file:
{
"key": "my-add-on",
"name": "Ping Pong",
"description": "My very first add-on",
"vendor": {
"name": "Ping Pong",
"url": "https://www.example.com"
},
"baseUrl": "{{localBaseUrl}}",
"links": {
"self": "{{localBaseUrl}}/atlassian-connect.json",
"homepage": "{{localBaseUrl}}/atlassian-connect.json"
},
"authentication": {
"type": "jwt"
},
"lifecycle": {
"installed": "/installed"
},
"scopes": [
"READ",
"WRITE"
],
"modules": {
"generalPages": [
{
"key": "hello-world-page-jira",
"location": "system.top.navigation.bar",
"name": {
"value": "Hello World"
},
"url": "/hello-world",
"conditions": [{
"condition": "user_is_logged_in"
}]
},
{
"key": "getissue-jira",
"location": "system.top.navigation.bar",
"name": {
"value": "Get Issue"
},
"url": "/getissue",
"conditions": [{
"condition": "user_is_logged_in"
}]
}
]
}
}
I am pretty sure this is not the correct way i am doing, Either i should use OAuth. But i want to make the JWT method for authentication work here.
Got it working by checking in here Atlassian Connect for Node.js Express Docs
Within JIRA ADD-On Signed HTTP Requests works like below. GET and POST both.
GET:
app.get('/getissue', addon.authenticate(), function(req, res){
var httpClient = addon.httpClient(req);
httpClient.get('rest/api/2/issue/ABC-1',
function(err, resp, body) {
Response = JSON.parse(body);
if(err){
console.log(err);
}else {
console.log('Sucessful')
}
});
res.send(response);
});
POST:
var httpClient = addon.httpClient(req);
var postdata = {
"fields": {
"project":
{
"key": "MYW"
},
"summary": "My Story Name",
"description":"My Story Description",
"issuetype": {
"name": "Story"
}
}
}
httpClient.post({
url: '/rest/api/2/issue/' ,
headers: {
'X-Atlassian-Token': 'nocheck'
},
json: postdata
},function (err, httpResponse, body) {
if (err) {
return console.error('Error', err);
}
console.log('Response',+httpResponse)
});
You should be using global variable 'AP' that's initialized by JIRA along with your add-on execution. You may explore it with Chrome/Firefox Debug.
Have you tried calling ?
AP.request(..,...);
instead of "var request = require('request');"
You may set at the top of the script follwing to pass JS hinters and IDE validations:
/* global AP */
And when using AP the URL should look like:
url: /rest/api/2/issue/ABC-1
instead of:
url: https://myaccount.atlassian.net/rest/api/2/issue/ABC-1
My assumption is that ABC-1 issue and user credentials are verified and the user is able to access ABC-1 through JIRA UI.
Here is doc for ref.: https://developer.atlassian.com/cloud/jira/software/jsapi/request/

I have created rest api using loopback and trying to call external api using rest connector and I want to display the result to the 1 api call

my case,I have create rest api which it should call external api and should display the response to the client using rest connector, i have added the below code in datasources.js
{"aci":{
"name": "aci",
"connector": "rest",
"operations": [{
"template": {
"method": "POST",
"url": "http://192.168.220.1:7800/esb/esb_cbs_service/AccountInfo",
"headers": {
"accepts": "application/json",
"content-type": "application/json"
},
"form": {
"ACCTINFOTRNRQ": {
"TRNUID": "12345",
"ACCTINFORQ": {
"DTACCTUP": "20050101"
}
}
},
"responsePath": "$.results[0].AccountInfoResponse.Item"
},
"functions": {
"acif": [
"customerId",
"customerName"
]
}
}]
}}
in model.js
module.exports = function(Acim) {
//remote method
Acim.extcall = function(Acim, cb){
cb(null, res);
}
};
Acim.remoteMethod('extcall',{
accepts: [{arg: 'customerId type" 'string''}]
returns: {arg: 'customerId', type: 'type'}
http: {path:'/getAci', verb: 'post'}
})
and when I reload the project I am facing this error. Please I am stuck here, what am I doing wrong?
C:\Users\user\acinfo>apic loopback:refresh
Updating swagger and product definitions
ERROR Cannot load the LoopBack application: Cannot load the LoopBack application: Cannot create data source "aci": Cannot initialize connector "RequestBuilder": Cannot read property 'root' of undefined
Please fix the problem and run apic loopback:refresh
Please fix the problem and run apic loopback:refresh

Resources