Firefox gives "301 Moved permanently" error on Http Request - json

I am currently developping an Angular 4 chat application, which make severals HTTP request.
On Google Chrome or Opera browser, all requests work fine but when I test my app on Firefox, one of them doesn't pass. I have already cleared my cache many times but the problem persists.
this.chatWebService.getLatestConversations(params).subscribe(
(response: CustomHttpResponse<ConversationModel[]>) => {
this.chatSharedService.setDiscussionList(response.data);
},
(errorResponse: HttpErrorResponse) => {
console.log(errorResponse)
});
And the request:
public getLatestConversations(p: { filter: string, search: string, page_index: number, page_count: number }): Observable<{}> {
const url = `${this.messagesUrl}?filter=${p.filter}&search=${p.search}&page_index=${p.page_index}&page_count=${p.page_count}`;
return this.http.get(url, { params: this.createHttpParams(p) });
}
private createHttpParams(params: {}): HttpParams {
const searchParams = new HttpParams();
const keys = Object.keys(params);
keys.forEach(key => searchParams.append(key, String(params[key])));
return searchParams;
}
On Firefox, this code gives me this error:
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of
the JSON data
Here is a sample of the returned JSON data:
{
"data": [
{
"type": "user",
"id": 76,
"name": "User 1",
"slug": "razx6k5nuser",
"muted": false,
"messages": [
{
"content": "Hi there",
"media": false,
"sent": 1516372902,
"read": true,
"sender": {
"id": 76,
"slug": "razx6k5nuser",
"lastname": "User lastname",
"firstname": "User first name",
"phoneNumber": ""
}
}
]
},
{
"type": "user",
"id": 71,
"name": "User 2",
"slug": "volc6p1suser",
"muted": false,
"messages": [
{
"content": "new message",
"media": false,
"sent": 1516358686,
"read": false,
"sender": {
"id": 77,
"slug": "razv6i2auser",
"lastname": "User lastname",
"firstname": "User first name",
"phoneNumber": ""
}
}
]
}
],
"meta": {
"page": "1",
"total": 18,
"totalNotRead": 1,
"totalMuted": 0
}
}
According to some errors I found on Google, it seems be solved by adding some headers for each request, so I have already added some headers on each of request with the interceptor, like this:
const request = req.clone({
setHeaders: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
But it still doesn't work. Can someone help me? Thank you in advance.

Related

FeathersJS Not Authenticated 401 Error when trying to use Access Token

In postman I am able to log in the user and get an accessToken:
Doing Post at http://localhost:3030/authentication I type in:
{
"strategy": "local",
"email": "bob#bob.com",
"password": "bob"
}
and then I get:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImFjY2VzcyJ9.eyJpYXQiOjE2NjEzMjgzMDEsImV4cCI6MTY2MTQxNDcwMSwiYXVkIjoiaHR0cHM6Ly95b3VyZG9tYWluLmNvbSIsImlzcyI6ImZlYXRoZXJzIiwic3ViIjoiMSIsImp0aSI6IjMyOWMwZTU3LTM5NTctNDUxOS05N2ZmLTRiNDIxOWI2MDQ2YSJ9.tIiRCMqzNg8F4lb1tzfYrOVvc148qRmZrZ7FPouHhKg",
"authentication": {
"strategy": "local",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImFjY2VzcyJ9.eyJpYXQiOjE2NjEzMjgzMDEsImV4cCI6MTY2MTQxNDcwMSwiYXVkIjoiaHR0cHM6Ly95b3VyZG9tYWluLmNvbSIsImlzcyI6ImZlYXRoZXJzIiwic3ViIjoiMSIsImp0aSI6IjMyOWMwZTU3LTM5NTctNDUxOS05N2ZmLTRiNDIxOWI2MDQ2YSJ9.tIiRCMqzNg8F4lb1tzfYrOVvc148qRmZrZ7FPouHhKg",
"payload": {
"iat": 1661328301,
"exp": 1661414701,
"aud": "https://yourdomain.com",
"iss": "feathers",
"sub": "1",
"jti": "329c0e57-3957-4519-97ff-4b4219b6046a"
}
},
"user": {
"id": 1,
"email": "bob#bob.com",
"createdAt": "2022-08-24T08:04:57.464Z",
"updatedAt": "2022-08-24T08:04:57.464Z"
}
}
But then when I try to use accessToken for another POST in Postman, I get:
{
"name": "NotAuthenticated",
"message": "Not authenticated",
"code": 401,
"className": "not-authenticated",
"errors": {}
}
Why is this?
One idea I have is maybe I did this part wrong. I thought I was supposed to add
auth.associateCurrentUser({
idField: "id",
as: "group_admin",
}),
But I was getting an error & found something online that said to change it to this (context below):
setField({
from: "params.user.id",
as: "data.group_admin",
}),
import * as authentication from "#feathersjs/authentication";
// Don't remove this comment. It's needed to format import lines nicely.
const { authenticate } = authentication.hooks;
import { setField } from "feathers-authentication-hooks";
export default {
before: {
all: [authenticate("jwt")],
find: [],
get: [],
create: [
setField({
from: "params.user.id",
as: "data.group_admin",
}),
// auth.associateCurrentUser({
// idField: "id",
// as: "group_admin",
// }),
],
update: [],
patch: [],
remove: [],
},
Do you have any ideas to get the accessToken to work with authentication?
I can post more code if needed.

Cypress login to REST endpoint is unauthorized, Postman works - upload of JSON file

We have a REST service with an incoming REST endpoint that accepts data. It has no web interface (Swagger or so), only the API. With Postman I can POST a JSON file (response code is 202) to it and then read the uploaded data from another endpoint.
When I want to log in to the same endpoint with Cypress to upload a JSON file from the fixtures folder (with the same body as in the Postman request), then I get response code 401 instead – Unauthorized. I have the feeling that the cypress request is wrong because the logfile of the service does not write a message when I use the cypress POST but it does when I use the Postman POST.
First question: What could I be doing wrong in the cypress request?
Second question: Once the authentication works, how can I POST/upload/push the content of the JSON file to that endpoint? Because I have no webpage to interact with, I cannot use click button functions. The documentation mainly deals with interpreting a JSON response but not with sending it.
My cypress code:
it('logs in to connector through REST API', () => {
cy.request({
method: 'POST',
url: 'localhost:8095/connector/demands/v1/demandData',
failOnStatusCode:false,
form: true,
body: {
Username: 'user',
Password: 'pass',
}
})
})
import my-request from '../fixtures/my-request.json'
it('loads the JSON file', () => {
cy.fixture('my-request.json')
})
The structure of the JSON file to upload is not too simple, here is a shortened version:
{
"#metadata": {
"context": "{{A}}"
},
"pool": "{{B}}",
"action": "NEW",
"Type": "ANNOUNCEMENT",
"ON": "Order123",
"PON": "PO123",
"SNN": "SN123",
"direction": "OUT",
"mode": 3,
"pack": [
{
"out": {
"outKey": "OUT14",
"outQuantity": "3",
"dimension": {
"length": "303",
"width": "33",
"height": "903",
"unit": "mm"
},
"layers": "3",
"weight": "3000",
"weightUnit": "grm",
"in": [
{
"inKey": "IN12",
"inQuantity": "3",
"article": {
"articleKey": "article3",
"quantity": "300",
"PON": "Art_PO300",
"SNN": "Art_SN300"
}
}
]
},
"p1": "pack3",
"p2": "pack4",
"store": true
},
{
"out": {
"outKey": "OUT23",
"outQuantity": "5",
"dimension": {
"length": "505",
"width": "55",
"height": "905",
"unit": "mm"
},
"layers": "5",
"weight": "5000",
"weightUnit": "grm",
"in": [
{
"inKey": "IN19",
"inQuantity": "5",
"article": {
"articleKey": "article5",
"quantity": "500",
"PON": "Art_PO500",
"SNN": "Art_SN500"
}
}
]
},
"p1": "pack5",
"p2": "pack5",
"store": true
}
]
}
Solution found. "form: true" must not be given because this overrides the content-type.
You can pass the contents of the fixture file(which is json) in the request body like this:
describe('Some Test Suite', function() {
// we can use these values to log in
const username = 'jane.lane'
const password = 'password123'
it('logs in to connector through REST API', () => {
cy.fixture('my-request.json').then(myFixture => {
cy.request({
method: 'POST',
url: 'localhost:8095/connector/demands/v1/demandData',
auth: {
username,
password,
},
failOnStatusCode: false,
form: true,
body: myFixture
})
})
})
})
For HTTP auth you have to use. You can check out this cypress recipe.
auth: {
username,
password,
}

how do i integrate authorize.net into my wix page?

I am using authorize.net's sandbox API to test their gateway in my wix (corvid/code) environment. Funny thing is that when i send JSON to the sandbox API i get a valid JSON response approving the (fake) transaction. however when i set it up thru wix i get data errors in my console. I have built on existing files that i have been able to run basic API responses, and more advanced auths with token responses. so the code works, just not with authorize.net. given my level of expertise, i think it might be something im doing wrong. i've done my due diligence, and there are no questions on this topic. here is my code:
///front end, from the corvid page's code
import {buyIt} from 'backend/authorizeNet';
export function button1_click(event) {
buyIt();
}
pretty basic, just calling code from my backend onClick. the filepath is correct. here is the module on the backend:
//// backend/authorizeNet.jsw
import {fetch} from 'wix-fetch';
export function buyIt() {
let data = {
"createTransactionRequest": {
"merchantAuthentication": {
"name": "***************",
"transactionKey": "****************"
},
"refId": "123456",
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": "5",
"payment": {
"creditCard": {
"cardNumber": "5424000000000015",
"expirationDate": "2020-12",
"cardCode": "999"
}
},
"lineItems": {
"lineItem": {
"itemId": "1",
"name": "vase",
"description": "Cannes logo",
"quantity": "18",
"unitPrice": "45.00"
}
},
"tax": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"duty": {
"amount": "8.55",
"name": "duty name",
"description": "duty description"
},
"shipping": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"poNumber": "456654",
"customer": {
"id": "99999456654"
},
"billTo": {
"firstName": "Ellen",
"lastName": "Johnson",
"company": "Souveniropolis",
"address": "14 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"shipTo": {
"firstName": "China",
"lastName": "Bayles",
"company": "Thyme for Tea",
"address": "12 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"customerIP": "192.168.1.1",
"transactionSettings": {
"setting": {
"settingName": "testRequest",
"settingValue": "false"
}
},
"userFields": {
"userField": [
{
"name": "MerchantDefinedFieldName1",
"value": "MerchantDefinedFieldValue1"
},
{
"name": "favorite_color",
"value": "blue"
}
]
}
}
}
}
return fetch("https://test.authorize.net/xml/v1/request.api", {
"method": "post",
"headers": {"Content-Type": "application/json"},
"body": data
})
.then(response => {console.log(response.json())});///if response.text is used, it gives details
}
note at the end of the backend code, calling response.json give me a json error, due to the return code contains HTML saying that i've requested invalid data. if i change it to response.text i get this in my console:
//console response with response.text
{...}
isFulfilled:
true
isRejected:
false
fulfillmentValue:
"<HTML><HEAD>\n<TITLE>Bad Request</TITLE>\n</HEAD><BODY>\n<H1>Bad Request</H1>\nYour browser sent a request that this server could not understand.<P>\nReference #7.1d60fea5.1557756725.387c74\n</BODY>\n</HTML>\n"
how do i get a good response from the API? like ive done with the same code in postman?
thanks in advance
return fetch(url, {
method: "post",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(data)
})
.then(response => console.log(response.text())
)
this got me the result i was looking for
stringify() converted my object to a JSON string. i still cannot get it to read the incoming JSON, might have to use parse...but if i read as text i get the info i want and my API is showing a successful transaction.

Set next step for the waterfall dialogue in Microsoft BotBuilder NodeJS SDK

I am using Microsoft Bot Framework for my facebook messenger bot. I want to load the dialog data from json files instead of hard coding in the js file. I would like to configure the next step in the dialog, based on result from the "current" step, which is part of the json file configuration, something like this.
{
"name": "welcome",
"type": "waterfall",
"steps": [
{
"id": 0,
"data": [
{
"type": "text",
"value": "Hey, It's nice to meet you."
},
{
"type": "quickReplies",
"value": "What do you want to do next?",
"options": [
{
"text": "some option 1",
"value": "option1"
},
{
"text": "some option 2",
"value": "option2"
}
]
}
],
"next": [
{
"result": "option1",
"action": "goto step 2"
},
{
"result": "option2",
"action": "goto step 5"
}
]
}
]
}
I would like to process all the incoming messages and respond with correct dialog or correct step in the dialog for the user.
I am trying something like this;
handleMessage = function (session) {
var step = session.dialogData["BotBuilder.Data.WaterfallStep"] || 0;
// check response data from previou step and identify the next step.
// set the waterfall step id
session.dialogData["BotBuilder.Data.WaterfallStep"] = 2;
session.send("Hello");
}
var bot = new builder.UniversalBot(connector, function (session) {
handleMessage(session);
})
.set('storage',tableStorage);
With this code, I am always getting step as zero for session.dialogData["BotBuilder.Data.WaterfallStep"] even after setting this to a different number.
Also, as soon as I set the waterfall step number, all other state data that is stored in my table storage for this conversation is gone.
Storage data before setting waterfall step:
{
"BotBuilder.Data.SessionState": {
"callstack": [
{
"id": "*:/",
"state": {
"BotBuilder.Data.WaterfallStep": 0
}
},
{
"id": "*:welcome",
"state": {
"BotBuilder.Data.WaterfallStep": 1
}
},
{
"id": "BotBuilder:prompt-text",
"state": {
"options": {
"prompt": {
"type": "message",
"agent": "botbuilder",
"source": "facebook",
"address": {
"id": "mid.$cAAAlr-0LRH9niO21L1hV6hs83GuJ",
"channelId": "facebook",
"user": {
"id": "XXXX",
"name": "XXXX"
},
"conversation": {
"isGroup": false,
"id": "XX"
},
"bot": {
"id": "XXX",
"name": "XXX"
},
"serviceUrl": "https://facebook.botframework.com"
},
"text": "what do you want to next"
//ignored for simplicity
},
"promptAfterAction": true,
"libraryNamespace": "*"
},
"turns": 0,
"lastTurn": 1517594116372,
"isReprompt": false
}
}
],
"lastAccess": 1517594112740,
"version": 0
}
}
After I set the waterfall step:
{
"BotBuilder.Data.SessionState": {
"callstack": [
{
"id": "*:/",
"state": {
"BotBuilder.Data.WaterfallStep": 2
}
}
],
"lastAccess": 1517602122416,
"version": 0
}
}
Interestingly the step number is saved to the database (but in session state) but my "session" variable do not have this value anywhere. Also, even after configuring custom state service, the serviceUrl is still https://facebook.botframework.com which I thought is the default state service used if there is no state service set for the bot.
Per your code, as your bot actually contains only one waterfall step: handleMessage(session);, which raised your issue. You can consider to create multiple dialogs from json configration instead of complex waterfall steps.
Here is my quick test, for your information:
const json = `
[{
"name": "welcome",
"type": "waterfall",
"steps": [
{
"id": 0,
"data": [
{
"type": "text",
"value": "Hey, It's nice to meet you."
},
{
"type": "quickReplies",
"value": "What do you want to do next?",
"options": [
{
"text": "some option 1",
"value": "option1"
},
{
"text": "some option 2",
"value": "option2"
}
]
}
],
"next": [
{
"result": "option1",
"action": "dialog2"
},
{
"result": "option2",
"action": "dialog3"
}
]
}
]
},{
"name":"dialog2",
"type": "waterfall",
"steps": [
{
"data": [
{
"type": "text",
"value": "Hey, this is dialig2."
}]
}
]
},{
"name":"dialog3",
"type": "waterfall",
"steps": [
{
"data": [
{
"type": "text",
"value": "Hey, this is dialig3."
}]
}
]
}]
`;
const generateSignleStep = (step) => {
return (session, args, next) => {
step.forEach(sentence => {
switch (sentence.type) {
case 'quickReplies':
let choices = sentence.options.map(item => {
return item.value
});
let card = new builder.ThumbnailCard(session)
.text(sentence.value)
.buttons(sentence.options.map(choice => new builder.CardAction.imBack(session, choice.value, choice.text)))
let message = new builder.Message(session).addAttachment(card);
builder.Prompts.choice(session, message, choices);
break;
case 'text':
default:
session.send(sentence.value)
break;
}
})
}
}
const generatenextAction = (actions) => {
return (session, args, next) => {
const response = args.response;
actions.map(action => {
if (action.result == response.entity) {
session.beginDialog(action.action);
}
})
}
}
const generateWaterfallSteps = (steps) => {
let waterfall = [];
steps.forEach(step => {
waterfall.push(generateSignleStep(step.data));
if (step.next) {
waterfall.push(generatenextAction(step.next));
}
});
return waterfall;
}
var bot = new builder.UniversalBot(connector);
const jsonobj = JSON.parse(json);
jsonobj.forEach(dialog => {
bot.dialog(dialog.name, generateWaterfallSteps(dialog.steps))
.triggerAction({
matches: new RegExp(dialog.name, "g")
})
});
The result is:

MongoDB, NodeJS: updating an embedded document with new members

Using: MongoDB and native nodeJS mongoDB driver.
I'm trying to parse all the data from fb graph api, send it to my API and then save it to my DB.
PUT handling in my server:
//Update user's data
app.put('/api/users/:fbuser_id/:category', function(req, res) {
var body = JSON.stringify(req.body);
var rep = /"data":/;
body = body.replace(rep, '"' + req.params.category + '"' + ':');
req.body = JSON.parse(body);
db.fbusers.update({
id: req.params.fbuser_id
}, {
$set: req.body
}, {
safe: true,
multi: false
},
function(e, result) {
if (e) return next(e)
res.send((result === 1) ? {
msg: 'success'
} : {
msg: 'error'
})
});
});
I'm sending 25 elements at a time, and this code just overrides instead of updating the document.
Data I'm sending to the API:
{
"data": [
{
"category": "App page",
"name": "SoundCloud",
"id": "7919071058",
"created_time": "2013-09-16T18:16:59+0000"
},
{
...and so on
}
]
}
Basically my API changes "data" key from sent json to the category name, f.e.:
PUT to /api/users/000/likes will change the "data" key to "likes":
{
"likes": [
{
"category": "App page",
"name": "SoundCloud",
"id": "7919071058",
"created_time": "2013-09-16T18:16:59+0000"
},
{
...and so on
}
]
}
Then this JSON is put to the db.
Hierarchy in mongodb:
{
"_id": ObjectID("556584c8e908f0042836edce"),
"id": "0000000000000",
"email": "XXXX#gmail.com",
"first_name": "XXXXXXXX",
"gender": "male",
"last_name": "XXXXXXXXXX",
"link": "https://www.facebook.com/app_scoped_user_id/0000000000000/",
"locale": "en_US",
"name": "XXXXXXXXXX XXXXXXXXXX",
"timezone": 3,
"updated_time": "2015-05-26T18:11:59+0000",
"verified": true,
"likes": [
{
"category": "App page",
"name": "SoundCloud",
"id": "7919071058",
"created_time": "2013-09-16T18:16:59+0000"
},
{
"category": "App page",
"name": "SoundCloud",
"id": "7919071058",
"created_time": "2013-09-16T18:16:59+0000"
},
{
....and so on
}
]
}
So the problem is that my api overrides the field (in this case "likes") with newly sent data, instead of appending it to already existing data document.
I am pretty sure that I should be using other parameter than "$put" in the update, however, I have no idea which one and how to pass parameters to it programatically.
Use $push with the $each modifier to append multiple values to the array field.
var newLikes = [
{/* new item here */},
{/* new item here */},
{/* new item here */},
];
db.fbusers.update(
{ _id: req.params.fbuser_id },
{ $push: { likes: { $each: newLikes } } }
);
See also the $addToSet operator, it adds a value to an array unless the value is already present, in which case $addToSet does nothing to that array.