Next.js webhook returns a 301 (redirect) instead of 200 - redirect

I have a Next.js app and I created an endpoint to handle a webhook from a third-party payment application.
The code for that endpoint is very simple, it checks that the order was paid and updates my database:
export default async function WebhookHandler(req, res) {
if (req.method === 'POST') {
const requestData = JSON.parse(req)
if (requestData.status === "paid") {
// Code to update database
}
res.status(200).json({ received: true });
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method not allowed.');
}
}
The problem is that this webhook is falling. When I go to my payment application logs, I can see the webhook requests are going to the right endpoint, but my endpoint response is a 301 (redirect) and the payment application expects a 200.
Any ideas why Next.js is creating this redirect? I don't even know where to look for this...

After a lot of digging, I found that it was my server configuration. It was redirecting my www.site.com to site.com 🤦‍♂️

Related

Facebook messenger platform webhook Verify Token not validated

I've created a facebook app on facebook developers
I've setup a local rails server and exposed it to public internet using ngrok. I'm receiving facebook's webhook validation GET request and I'm returning the hub_challenge code in response. The response status code is also 200. I've provided a secret Verify Token which is required to set up a messenger webhook. But after all this I'm getting error
The Callback URL or Verify Token couldn't be validated. Please verify
the provided information or try again later.
I've checked that the request is received and the response being sent back to the facebook server, but don't know why it fails and says Verify Token couldn't be validated. Is it some special token that I have to get from somewhere from facebook messenger platform? Currently I've provided it my own secret token. Any help will be appreciated. Thanks
when I verify Facebook Webhook with my website i got that kind error
The URL couldn't be validated. Response does not match challenge, expected value="1421256154", received="1421256154\u003Clink rel=..."
My code
public function verify_token(Request $request)
{
$mode = $request->get('hub_mode');
$token = $request->get('hub_verify_token');
$challenge = $request->get('hub_challenge');
if ($mode === "subscribe" && $this->token and $token === $this->token) {
return response($challenge,200);
}
return response("Invalid token!", 400);
}
my code everything is ok .I am using laravel thats why APP_DEBUG=true defalt when I change it APP_DEBUG=false its working and my problem solved.

Facebook Webhook Test Button not working as expected

I have successfully added my callback url in my webhooks setup. At that time, the callback url was called successfully with proper logs and everything in the server. But when I click on the TEST button for the respective name (leadgen in this case), nothing AT ALL is being received by the server when in fact it should at least log the very first line. Note that I am using post and get.
Additional note: for NetSuite experienced developers, I am using a suitelet as the callback url for the webhook.
Thanks.
Suitelets that are available externally without login will only work if the User-Agent header in the request mimics a browser. See for example SuiteAnswers # 38695.
I ran into a similar issue, and the workaround was to proxy the request using a Google Cloud Function that simply rewrote the User Agent:
const request = require('request');
exports.webhook = (req, res) => {
request.post(
{
url: process.env.NETSUITE_SUITELET_URL,
body: req.body,
json: true,
headers: {
'User-Agent': 'Mozilla/5',
Authorization: req.headers['authorization'],
},
},
function(error, response, body) {
res.send(body);
}
);
};

Can't resolve Dropbox.com redirects with Axios or D3-fetch

I'm trying to fetch data in the browser from a Dropbox link: https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1
Using Axios this works in Node:
axios.get('https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1').then(x => {
console.log('Received correctly')
console.log(x.data);
}).catch(error => {
console.log('Error', error.message);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
}
console.log(error)
});
https://runkit.com/stevebennett/5dc21d04bbc625001a38699b
However it doesn't work in the browser (click the "Console" tab):
https://codepen.io/stevebennett/pen/QWWmaBy
I just get a generic "Network Error". I see the 301 Redirect being retrieved, which seems perfectly normal, but for some reason, it is not followed.
Exactly the same happens with D3: "NetworkError when attempting to fetch resource."
https://codepen.io/stevebennett/pen/KKKoZYN
What is going on?
This appears to be failing because of the CORS policy. Trying this with XMLHttpRequest directly fails with:
Access to XMLHttpRequest at 'https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS isn't allowed on www.dropbox.com itself.

Redirect after user has logged in

I'm pretty new to Angular, and right now I'm just trying to get all my routes set up and working as I'd like.
Setup:
When a user navigates to certain pages (/settings for this example) the app should check if there is a user already logged in. If there is continue as usual. Otherwise the user should go to the login page (/login).
What I'd like:
After the user has successfully logged in they should go to the page they were originally trying to get to (/settings)
My question:
Is there an "Angular way" to remember where the user was trying to go to?
Relevant code:
app.js
.when('/settings', {
templateUrl: '/views/auth/settings.html',
controller: 'SettingsCtrl',
resolve: {
currentUser: function($q, $location, Auth) {
var deferred = $q.defer();
var noUser = function() {
//remember where the user was trying to go
$location.path("/login")
};
Auth.checkLogin(function() {
if (Auth.currentUser()) {
deferred.resolve(Auth.currentUser());
} else {
deferred.reject(noUser());
}
});
return deferred.promise;
}
}
})
login.js
$scope.submit = function() {
if(!$scope.logInForm.$invalid) {
Auth.login($scope.login, $scope.password, $scope.remember_me)
//go to the page the user was trying to get to
}
};
Much thanks to John Lindquist for the video which got me this far.
First off, you do not want to redirect the user to a login page.
An ideal flow in a single page web app is as follows:
A user visits a web site. The web site replies with the static assets for the
angular app at the specific route (e.g. /profile/edit).
The controller (for the given route) makes a call to an API using $http, $route, or other mechanism (e.g. to pre-fill the Edit Profile form with details from the logged in user's account via a GET to /api/v1/users/profile)
If/while the client receives a 401 from the API, show a modal to
login, and replay the API call.
The API call succeeds (in this case, the user can view a pre-filled Edit Profile form for their account.)
How can you do #3? The answer is $http Response Interceptors.
For purposes of global error handling, authentication or any kind of
synchronous or asynchronous preprocessing of received responses, it is
desirable to be able to intercept responses for http requests before
they are handed over to the application code that initiated these
requests. The response interceptors leverage the promise apis to
fulfil this need for both synchronous and asynchronous preprocessing.
http://docs.angularjs.org/api/ng.$http
Now that we know what the ideal user experience should be, how do we do it?
There is an example here: http://witoldsz.github.com/angular-http-auth/
The example is based on this article:
http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application
Good luck and happy Angularing!

ASP.NET MVC Authorize Attribute does a 302 redirect when the user is not authorized

MSDN explicitly says it should do 401 redirect, but I'm getting a 302 redirect on FF, and this is causing problems in AJAX requests as the returned status is 200 (from the redirected page).
http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx
I've found someone else with the same problem:
http://blog.nvise.com/?p=26
Any other solution, besides his?
I really like this solution. By changing the 302 response on ajax requests to a 401 it allows you to setup your ajax on the client side to monitor any ajax request looking for a 401 and if it finds one to redirect to the login page. Very simple and effective.
Global.asax:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302 &&
Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
}
}
Client Side Code:
$(function () {
$.ajaxSetup({
statusCode: {
401: function () {
location.href = '/Logon.aspx?ReturnUrl=' + location.pathname;
}
}
});
});
The Authorize attribute does return a Http 401 Unauthorized response. Unfortunately, however if you have FormsAuthentication enabled, the 401 is intercepted by the FormsAuthenticationModule which then performs a redirect to the login page - which then returns a Http 200 (and the login page) back to your ajax request.
The best alternative is to write your own authorization attribute, and then if you get an unauthenticated request that is also an Ajax request, return a different Http status code - say 403 - which is not caught by the formsAuthenticationModule and you can catch in your Ajax method.
I implemented my own custom authorize attribute which inherited from AuthorizeAttribute and ran into the same problem.
Then I found out that since .Net 4.5 there is a solution to this - you can suppress the redirect in the following way:
context.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
Then the response will be a 401 - Unauthorized, along with the HTTP Basic authentication challenge.
More info here
If you are using a ASP.NET MVC 5 Web Application go to App_Start -> Startup.Auth.cs. Check if app.UseCookieAuthentication is enabled and see if CookieAuthenticationOptions is set to LoginPath = new PathString("/Login"), or similar. If you remove this parameter 401 will stop redirecting.
Description for LoginPath:
The LoginPath property informs the middleware that it should change an
outgoing 401 Unauthorized status code into a 302 redirection onto the
given login path. The current url which generated the 401 is added to
the LoginPath as a query string parameter named by the
ReturnUrlParameter. Once a request to the LoginPath grants a new
SignIn identity, the ReturnUrlParameter value is used to redirect the
browser back to the url which caused the original unauthorized status
code. If the LoginPath is null or empty, the middleware will not look
for 401 Unauthorized status codes, and it will not redirect
automatically when a login occurs.