Avoiding http error 405 while executing an put command with angularjs - angularjs

First to say, when I enter the put command in POSTMAN (its then a POST there) I have no problems. Trying to execute the PUT command in code I receive a http 405 error.
The exact error is:
<p>Problem accessing /api/portfolio/createTransaction. Reason:
<pre> Method Not Allowed</pre></p><hr>
This is my code:
const app = angular.module('demoAppModule', ['ui.bootstrap']);
const apiBaseURL = "/api/portfolio/";
console.log(apiBaseURL);
app.controller('DemoAppController', function($scope, $http) {
const demoApp = this;
demoApp.createTransaction = function () {
console.log("Initiating createTransaction...")
var transactionDetails = $.param({
Reference: $scope.reference,
Quantity: $scope.quantity,
TradeDate: $scope.tradeDate,
});
const createTransactionURL =
apiBaseURL
+ "createTransaction";
console.log("Executing flow");
console.log("Transaction URL = " + createTransactionURL);
console.log("Transaction Details = " + transactionDetails);
$http.put(createTransactionURL, angular.toJson(transactionDetails))
.then(function (transactionDetails, status, headers){
$scope.ServerResponse = transactionDetails;
})
.catch(function (transactionDetails, status, header, config) {
$scope.ServerResponse = htmlDecode("transactionDetails: " + transactionDetails +
"\n\n\n\nstatus: " + status +
"\n\n\n\nheaders: " + header +
"\n\n\n\nconfig: " + config);
});
};
});
Appreciate any help!

The server is rejecting your request, likely because it doesn't allow PUT requests.
It's probably expecting a HTTP POST instead of a PUT.
If so, change $http.put to $http.post - the method signatures are identical.
If you think the server should be accepting a PUT, you'll need to check why the server side code is rejecting it, which won't be apparent in the client code

Related

Getting Spotify Token w fetch fails on Android but works on iOS - using Expo

This is my code trying to get a token from the Spotify API, the "code" value in "dataToSend" is from authentication which works fine, but then I get [Unhandled promise rejection: TypeError: Network request failed] after the POST request (fetch) executes.
try{
var dataToSend = {
code: code,
redirect_uri: makeRedirectUri(),
grant_type: 'authorization_code'};
//making data to send on server
var formBody = [];
for (var key in dataToSend) {
var encodedKey = encodeURIComponent(key);
var encodedValue = encodeURIComponent(dataToSend[key]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
//POST request
var response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST', //Request Type
body: formBody, //post body
headers: {
//Header Defination
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')),
},
})
console.log(response.status, "RESPONSE")
return await response.json()
}catch (error){
console.log(error,error.toString(),"code: " + code)
return error.toString()
}
I tried logging the response status to look for an https code but since this whole thing is inside a try-catch block the code exits before even reaching the console.log. Because of that I'm thinking the issue is something else other than just a bad request because otherwise the fetch request would still go through and the code would continue past the console.log line (I think?).
This same code works on iOS but not Android. I tried running the app on localhost, LAN, Tunnel, and the published version as well (expo published) in case it's something funky with that but nothing seems to work.

Angular HTTP Basic Auth logout header change ignored

I'm using basic HTTP auth (without SSL for testing).
The login works fine, we send an $http request with the authorization header and if the login is correct, it works.
For logout, I'm setting the Authorization header to a bad value and sending an $http request to "trick" the server. The server seems to ignore the new changed auth header. I verified with developer tools in FF that the header value is all ones, but the request is still successful.
How do I "logout"? The logout function sends a bad Authorization header, and the browser sends it according to firebug. What's going on? This is a Java EE 7 app with Wildfly 9 and Shiro, if that makes a difference.
Here is the code:
var DataFactory = function($http, $rootScope, $base64, $cookieStore) {
var _debug = false;
function _d(message) {
if (!_debug) {
return;
}
console.log(message);
}
function setDebug(flag) {
_debug = flag;
}
function doLogout() {
_d("Logging out");
$rootScope.globals = {};
$cookieStore.remove('globals');
$http.defaults.headers.common['Authorization'] = 'Basic 111111111111111111';
$http.get(
'http://localhost:8080/myapp/rest/v1/svc')
.then(function(data) {
alert("Logout: " + JSON.stringify(data.data));
}, function(data) {
alert("Logout Error: " + JSON.stringify(data))
});
}
function doLogin(username, password) {
var token = $base64.encode(username + ":" + password);
_d("Logging " + username + " in with token " + token);
$http.defaults.headers.common['Authorization'] = 'Basic ' + token; // jshint
// ignore:line
$rootScope.globals = {
token : token,
username : username
};
$cookieStore.put("globals", $rootScope.globals);
_d("Login finished, globals are: " + JSON.stringify($rootScope.globals));
$http.get(
'http://localhost:8080/myapp/rest/v1/svc')
.then(function(data) {
alert(JSON.stringify(data.data));
}, function(data) {
alert("Error: " + JSON.stringify(data))
});
}
;
return {
setDebug : setDebug,
doLogin : doLogin,
doLogout : doLogout
};
}
Sending your own authorization string within a XHR request will not magically delete the information cached in the browser. Basic authentication has no concept of logging out. The only way to "logout" with basic authentication is to make the credentials invalid at the server, i.e. change username and/or password so that the stored credentials do not work any longer.

Unit testing $httpBackend angular no response defined

I'm struggling in my first test so please bear with me.
I want to test a function that make a http post:
$scope.formData= 'client=' + $scope.client_selected + '&version=' + $scope.version_selected + '&modules=' + $scope.client.modules;
var response = $http.post('http://localhost:8080/mavenproject8/lol/form', $scope.formData);
response.success(function (data, status, headers, config) {
$scope.validity = true;
$scope.status = "true";
});
response.error(function (data, status, headers, config) {
$scope.status = "false";
alert("Exception details: " + JSON.stringify({data: data}));
and my test looks like this:
...
beforeEach(inject(function ($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
$httpBackend.when('POST', 'http://localhost:8080/mavenproject8/lol/form', data)
.respond([200, {success: true, errors: [{}]}]);
and this is the it block:
it('should succeed when everything is correct', function () {
$rootScope.client.modules=["360"];
$rootScope.version_selected="2.4.0"
$rootScope.client_selected="NSM";
$rootScope.formData='client=' + $rootScope.client_selected + '&version=' + $rootScope.version_selected + '&modules=' + $rootScope.client.modules;
$httpBackend.expectPOST('http://localhost:8080/mavenproject8/lol/form',$rootScope.formData);
$rootScope.myFunc();
expect($rootScope.validity).toBe(true);
});
But this test doesn't pass, with the error:
Error: No response defined !
I feel like I'm so close but I can't make it work. I would be grateful if you could help me. Thank you!
Actually, your expected post request doesn't specify a response, that's why you see that error, so all what you have to do is:
$httpBackend.expectPOST('http://localhost:8080/mavenproject8/lol/form').respond(200,{});
//don't forget to make the flush after the function call.!!
$rootScope.myFunc();
$httpBackend.flush();
( you can dont need the $httpBackend.whenPost because that's useful when you want to create a back end definition, and specify the response( get case for example) so you can remove it, and your test will still pass.)

How do I use $resource to post to a web-service?

I'm not very good with angular. I want to post to a web service, sending some xml with my search parameters. I don't want to send the parameters in the query string. I've read the official documentation, but I'm still confused. I'm mostly hung up on how to define the $resource to be able to post the way I want.
The error I get is: POST 'https://someWebservice/searchnet'::ERR_INSECURE_RESPONSE
My code is below:
'use strict';
angular.module('app').controller('inventorySearchController', inventorySearchController);
inventorySearchController.$inject = ['$scope','$http', '$resource'];
function inventorySearchController($scope, $http, $resource) {
console.log("controller initialized...");
$scope.callService = function(){
console.log("callService function called...");
var urlSearchService = 'https://someWebservice/search';
var skuVal = $scope.skuField;
var mVenVal = $scope.mVendorField;
//need to somehow specifiy that xml is a #FormParam
var xmlItemSearchRequest = "<ItemSearchRequest>"
+"<skuid>" + skuVal + "</skuid>"
+"<mvendor>" + mVenVal + "</mvendor>"
+"</ItemSearchRequest>";
console.log('calling: ' + urlSearchService + 'sending xml: ' + xmlItemSearchRequest);
var Results = $resource(urlSearchService, {
save: {
method: 'POST',
isArray: true
}
});
var result = Results.save();
console.log('Results: ' + Results);
console.log('result: ' + result);
var successfunction = function(){
$scope.searchResults = data;
console.log('call to ' + urlSearchService + ", was a success.");
};
var errorfunction = function(){
console.error('Calling error', status, data);
};
};
};
The error shown is not about how you posted data. Instead, response was not signed by a valid SSL certificate (or the certificate could not be accepted). That is due to the use of HTTPS protocol. You should consider using HTTP instead.
You can try the approach suggested here to confirm that this is the case.

Authentication with Azure using OAuth2 for an ionic mobile app

I have been trying to retrieve the token from Azure AD by posting in the username and password using the HTTP angular service. Unfortunately, I always get this error:
Failed to load resource: the server responded with a status of 400 (Bad Request)
It complains the following: "The request body must contain the following parameter: 'grant_type'"
Does anyone have any idea what this is happening?
This is my login controller and I have set up my Azure AD already.
function access() {
var username = vm.username.trim();
var password = vm.password.trim();
requestAccessToken(username, password);
}
function requestAccessToken(username, password){
var base_url = 'https://login.windows.net';
var client_id = "35d16a1c-3f01-402a-9346-ee13b0aa2ba0";
var params = '?grant_type=password&client_id=' + client_id + '&username=' + username + '&password=' + password;
var path = "/4397b89d-d9d7-4d27-9cac-f7ae0ff0d880/oauth2/token";
//var path = "/common/oauth2/token"; we have tried this one too
var url = base_url + path + params;
$http.post(url).success(getAccessTokenSuccess).error(getAccessTokenFailure);
}
function getAccessTokenSuccess(data, status, header, config) {
console.log('data: ', data);
}
function getAccessTokenFailure(data, status, header, config) {
console.log('data: ', data);
}
It looks like you need to send grant_url in the request body (that implies the HTTP request is probably a POST), not as a query parameter, which is what you are doing.

Resources