How can I make HTMX display a 403 error page returned from a hx-delete request? - htmx

In my project, when the web browser submits a hx-delete request, and the backend determines the user doesn't have the required permissions for that request, the backend returns a full 403 error page. By default HTMX ignores this response. I would like HTMX to instead display the full 403 error page.
How can I do this?

I solved my problem by adding this code to the page.
/***
* Swaps in the body of error pages returned from htmx requests
*/
document.addEventListener("htmx:beforeOnLoad", function (event) {
const xhr = event.detail.xhr
if (xhr.status == 500 || xhr.status == 403 || xhr.status == 404) {
event.stopPropagation() // Tell htmx not to process these requests
document.children[0].innerHTML = xhr.response // Swap in body of response instead
}
})

Related

Lambda#edge redirect gets in a redirect loop

I have a static website on aws s3. Have setup route 53 and cloud front and everything works smoothly. s3 Bucket is setup to serve index.html as index document.
Now I have added another file called index-en.html that should be served when the request country is any other country and not my home country.
For this I have added a lambda#edge function with the following code:
'use strict';
/* This is an origin request function */
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
/*
* Based on the value of the CloudFront-Viewer-Country header, generate an
* HTTP status code 302 (Redirect) response, and return a country-specific
* URL in the Location header.
* NOTE: 1. You must configure your distribution to cache based on the
* CloudFront-Viewer-Country header. For more information, see
* http://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers
* 2. CloudFront adds the CloudFront-Viewer-Country header after the viewer
* request event. To use this example, you must create a trigger for the
* origin request event.
*/
let url = 'prochoice.com.tr';
if (headers['cloudfront-viewer-country']) {
const countryCode = headers['cloudfront-viewer-country'][0].value;
if (countryCode === 'TR') {
url = 'prochoice.com.tr';
} else {
url = 'prochoice.com.tr/index-en.html';
}
}
const response = {
status: '302',
statusDescription: 'Found',
headers: {
location: [{
key: 'Location',
value: url,
}],
},
};
callback(null, response);
};
I have also edited cloud front behavior to whitelist Origin and Viewer-country headers and setup the cloudfront Viewer-Request event and lambda Function ARN relation.
However I get a "too many redirect error".
I have 2 questions:
How to correct the "too many redirects error"?
For viewers outside "TR" the default landing page should be index-en.html, from which 2 more pages in english are accessible via navigation menu. So when users request a specific page from page navigation they should be able to access those pages, when no page is requested the default landing page should be served.
Appreciate help.
Thanks.
You are creating a redirect loop because you are sending the viewer back to the same site, same page, no matter what the results of your test.
if (countryCode === 'TR') {
return callback(null, request);
} else {
...
callback(null,request) tells CloudFront to continue processing the request -- not generate a response. Using return before the callback causes the rest of the trigger code not to run.

How to Redirect back to the failed Resource after successful authentication with Auth0

When unauthenticated user trying to access Resource the authProvider function is called with FETCH_ERROR type:
if (type === AUTH_ERROR) {
const { status } = params;
if (status === 401 || status === 403) {
return Promise.reject();
}
}
Status 401 or 403 triggering the authProvider() with AUTH_LOGOUT type and then redirection to /login page.
The login page calls the auth0-js.authorize() method, which redirects to the auth0 authentication page and, after authentication, redirects back to the login page.
Which is the right way to do redirect back to failed Resource after successful authentication on login page?
userLogin(payload, pathName) is called, but how to restore path to failed Resource?
Should it be saved to localStorage on AUTH_ERROR?

Vuejs http request always attach a query parameter

Am using a query param authentication with my backed that requires all http requests have the following
access-token=token
AM using vuejs2 resource
So in my request i want to intercept every request and attach the above so i have
Vue.http.interceptors.push(function (request, next) {
//here add the access token in my url string
//am stuck
next()
});
So i expect when i try
this.$http.get('users')
the request should automatically be
users?access-token=token
Also when ihave
this.$http.get('users?pagination=10')
then request url should have
users?pagination=10&access-token=token
How do i intercept all the requests and attach the query parameter access token
THe way i was able to resolve this was by
if(request.url.indexOf("?") === -1){ //means no access token since nothing is passed to the url
request.url = request.url+"?access-token=token";
}else{
if(request.url.indexOf("access-token") === -1){
request.url = request.url+"&access-token=token"
}
}

Express js Redirect not rendering page

I am trying to redirect the user that uses my website after he has logged into his account, he will be redirected to a dashboard.
The problem is that I can see a request for the /dashboard route in the Network tab of the browser Inspection Tools, but the page never loads.
This is my code so far.
router.post('/login', function(request, response){
// verify against database and send back response
var userData = {};
userData.email = request.body.email;
userData.password = request.body.password;
userData.rememberPassword = request.body.rememberPassword;
// check if in the database and re-route
var query = database.query('SELECT * FROM users WHERE email = ?', [userData.email], function(error, result){
if(error){
console.log('Error ', error);
}
if(result.length){
// check if the password is correct
if(userData.password === result[0].password){
// redirect to the dashboard
// TODO this piece of code does not redirect correctly
response.redirect('/dashboard'); // < HERE
console.log('Haha');
}
}
else{
// do something when there is are no results
// invalid email status code
response.statusCode = 405;
response.send('');
}
});
});
And this is the route towards the dashboard, and it is being rendered properly when accessed in the browser.
router.get('/dashboard', function(request, response){
response.render(path.resolve(__dirname, 'views', 'dashboard.pug'));
});
Why can't it redirect when the user completes the login process?
Thanks.
The issue can be in the frontend and not in the backend. If you are using AJAX to send the POST request, it is specifically designed to not change your url.
Use window.location.href after AJAX's request has completed to update the URL with the desired path.But the easiest way would be to create a form with action as /login and use the submission to trigger the url change.
To make sure that the problem does not lie with the backend,
Add a logging statement to router.get('/dashboard' to verify if
the control was passed.
Check that the HTTP status code of the /login route is 302 indicating a redirect and location header has the route /dashboard.
Content type of response /dashboard is text/html.If not please set it using res.setHeader("Content-Type", "text/html").

Where do you place NPM's request code?

I want to use the request module in my express app, but I am not sure where the actual requests code goes.
Usage:
When a user loads a page, make a GET request and populate the page with data.
When a users clicks on a item from a table, make a GET request.
When a user fills out a form, POST.
I tried searching for answers but it seems to be implied that the developer knows where to place the code.
Example of a code snippet using request that I am unsure where to place in the express app:
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
I am guessing that I should not place the code in the server.js file especially if I am going to be making many different calls, but that's what it looks like others are doing on StackOverflow.
Does the request belong in a model?
If you are doing this in response to a user interaction, like clicking on something you can just do it from the route handler. Below, I just return the results to the client, or I pass an error to the next handler in the chain.
var request = require('request');
var express = require('express');
var app = express();
app.get('/click', function(req, res, next){
request('http://www.google.com', function (error, response, body) {
if (error || response.statusCode != 200)
return next(err);
response.send(body) // return the html to the client
})
});
app.listen(3000);
In bigger apps you might move routes into separate modules.