nuxt-mail fails with a 504 with nginx reverse proxy - vue.js

I configured nuxt-mail to send emails from our nuxt app.
The baseURL of my app is changed to "https://localhost:3000/app" instead of "https://localhost:3000"
So, nginx redirects all calls to '/' to a static app. And all calls to '/app' to a dynamic app.
The issue is that on production, nuxt-mail is unable to send email through a post to '/app/mail/send'.
I tried with setting axios baseURL on nuxt.config.js as suggested on the nuxt-mail npm/github page
I don't see a path to send or mail in .nuxt/router.js
file: contact.vue
Note: WEBSITE_DOMAIN points to https://localhost:3000 locally and valid web domain on production in this format: https://www.production_website.com
<script>
...
methods: {
...
sendMail(){
this.$axios.post(
this.$config.WEBSITE_DOMAIN+'/app/mail/send',
{
...
}
...
}
...
</script>
file: nuxt.config.js
...
export default{
...
router: {
base: '/app/'
},
...
}
Note: I did configure the upstream logs from nginx to app server
Access log from nginx on production
49.205.150.249 - - [04/May/2022:15:30:54 +0000] "POST /app/mail/send HTTP/1.1" 504 167 "https://www.<xxxxxxxxx_NAME>.com/app/contact"
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:99.0) Gecko/20100101
Firefox/99.0"
Error log from nginx on production
2022/05/04 15:30:54 [error] 2106#2106: *38 upstream timed out (110:
Connection timed out) while reading response header from upstream,
client: 49.205.150.249, server: <xxxxxxxxx_NAME>.com, request: "POST
/app/mail/send HTTP/1.1", upstream:
"https://<xxxxxxxxx_IP>:3000/app/mail/send", host:
"www.<xxxxxxxxx_NAME>.com", referrer:
"https://www.<xxxxxxxxx_NAME>.com/app/contact"
What am I missing here? It works perfectly on my staging though.

The port allowing SMTP on the production instance was not open. On AWS EC2, I needed to enable outbound rules on the corresponding security group.

Related

Error in Postman: Error: write EPROTO 8768:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:

During request GET in Postman (https://localhost:9001/test)
I've received an error:
Error: write EPROTO 8768:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:c:\users\administrator\buildkite-agent\builds\pm-electron\postman\electron-release\vendor\node\deps\openssl\openssl\ssl\record\ssl3_record.c:252:
Warning: This request did not get sent completely and might not have all the required system headers.
Postman Configuration:
SSL certificate verification is disabled;
Proxy configuration - Default Proxy Configuration and Proxy configurations for sending requests are disabled;
Request timeout in ms - 0.
For Localhost we don't really need https, please try with http://localhost:9001/test
check that you are using the HTTP protocol not HTTPS to send requests to the server:
example
export const config = {
baseUrl: "http://localhost:4000"
}
it has to be the http not https for localhost
"http://localhost:3000"
NOT
"https://localhost:3000"
const transporter = nodemailer.createTransport({
host:'smtp.gmail.com',
port:587,
secure:false,
requireTLC:true,
auth: {
user:'youmail#gmail.com',
pass:'youpass'
}
}
Notice that secure: is false.
The error occurs when secure: is true.
the reason was in an incorrect link.
In the controller I have used
#RequestMapping(value="/{baseSiteId}/test")
And this {baseSiteId} was not what I expected.

Safari doesn't send cookie to Express when requesting image via p5 loadImage()

Background
I set up an Express.js app behind a proxy to let users to login before being directed to a web app. This app is failing to serve up some images in Safari (macOS/iOS) because Safari is not sending the cookie back with requests for images that originate from the loadImage() method in my p5.js code. This does not happen on Chrome (macOS).
When I load the page, the browser requests the resources fine. But requests originating from my application returns a different session, which is not logged in, and gets caught by Express:
// Request for the main page by the browser
Session {
cookie:
{ path: '/',
_expires: 2020-05-04T16:26:00.291Z,
originalMaxAge: 259199998,
httpOnly: true,
secure: true },
loggedin: true }
// Request for image assets by a script in my application
Session {
cookie:
{ path: '/',
_expires: 2020-05-04T16:26:00.618Z,
originalMaxAge: 259200000,
httpOnly: true,
secure: true } }
HTTP Requests from Safari
GET https://mydomain/app/img/svg/Water.svg HTTP/1.1
Host: mydomain
Origin: https://mydomain
Connection: keep-alive
If-None-Match: W/"5e6-171c689d240"
Accept: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
If-Modified-Since: Wed, 29 Apr 2020 15:24:13 GMT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
Referer: https://mydomain/app/
Accept-Language: en-us
Accept-Encoding: gzip, deflate, br
HTTP/1.1 302 Found
Date: Fri, 01 May 2020 06:50:07 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.3.17
X-Powered-By: Express
Location: /
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 23
Access-Control-Allow-Origin: *
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Found. Redirecting to /
Express app
The app is set up behind an HTTPS proxy, so I set the Express Session object to trust proxy and set security to auto (setting to false doesn't fix the problem):
app.set('trust proxy', 1)
app.use(session({
secret: 'my-secret',
resave: true,
saveUninitialized: true,
cookie: {
secure: 'auto',
maxAge: 259200000
}
}));
When the user signs in, it is sent to /auth to check against the database
app.post('/auth', function (request, response) {
var user = request.body.user;
var password = request.body.password;
if (user && password) {
connection.query('SELECT * FROM accounts WHERE user = ? AND password = ?', [user, password], function (error, results, fields) {
if (results.length > 0) {
request.session.loggedin = true;
// If the user logs in successfully, then register the subdirectory
app.use("/app", express.static(__dirname + '/private/'));
// Then redirect
response.redirect('/app');
} else {
response.send('Incorrect password!');
}
response.end();
if (error) {
console.log(error);
}
});
} else {
response.send('Please enter Username and Password!');
response.end();
}
});
They are redirected to /app when logged in:
app.all('/app/*', function (request, response, next) {
if (request.session.loggedin) {
next(); // allow the next route to run
} else {
// The request for images from my p5 script fails and these request redirect to "/"
response.redirect("/");
}
})
Question
What can I do to ensure Safari pass the session cookie with its request so that Express will return the correct asset?
Edit
Including the function that invokes loadImage(). This is embedded in an ES6 class that loads image assets for particles in a chemical simulation. This class must successfully resolve promises so other higher order classes can set correct properties.
loadParticleImage() {
return new Promise((resolve, reject) => {
loadImage(this.imageUrl, (result) => {
// Resolves the Promise with the result
resolve(result);
}, (reason) => {
console.log(reason);
});
})
}
Edit #2
Including the headers for a successful request directly to the URL of the image asset:
GET https://mydomain/app/img/svg/Water.svg HTTP/1.1
Host: mydomain
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cookie: connect.sid=s%3A2frOCv41gcVRf1J4t5LlTcWkdZTdc8NT.8pD5eEHo6JBCHcpgqOgszKraD7AakvPsMK7w2bIHlr4
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
Accept-Language: en-us
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
I suggest using express's static middleware to serve static files. With this, you won't need any session to get images, js, css, etc. Also, it accelerates your application. You need to place
app.use(express.static( ... ))
before the app.use(session( ... )) statement if you want some additional perfomance, because if you do, express won't attepmt to creare session for static files.
The fetch() call in the source code for that loadImage() function is not setting the credentials option that controls whether cookies are included with the request or not, therefore they are not sent with the request.
Do you really need authentication before serving an image? If not, you could rearrange the way you serve images in your server so that they can be served without authentication using express.static() pointed at a directory that contains only resources that can be served without authentication. If they do need to be authenticated, you may have to patch the loadImage() code to use the credentials: include option or load your images a different way.

Issue with accessing Jenkins api with Vue/Axios call

I tried making a get call with axios from my Vue js codebase/ environment to Jenkins API and I'm unable to do so.
I've read every resource that I could but wasn't able to fix this particular problem. I even created a .htaccess file to see if it help but wasn't useful.I ran out of options so I came here for help.
Below are the axios codes that I used within my App.vue file.
axios.get(
*URL to access Jenkins that is currently running on a tomcat server*,
{
headers: {
"jenkins-crumb": "* Some numbers and letters*",
},
auth: {
username: "*obvious username*",
password: "*obvious password*"
},
withCredentials: true,
crossdomain: true
}
)
.then(response => (this.info= response)).catch(error => (console.log(error)));
Console log output:
Access to XMLHttpRequest at 'url' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Network output:
General
Request URL: URL
Request Method: OPTIONS
Status Code: 403
Remote Address: localhost:8080
Referrer Policy: no-referrer-when-downgrade
Request Headers
Provisional headers are shown
Access-Control-Request-Headers: authorization,jenkins-crumb
Access-Control-Request-Method: GET
Origin: http://localhost:8080
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Please help!

Issue with set cookie headers from server and vue component vue-beautiful-chat

I have this issue on a Vue app, based on component vue-beautiful-chat: I make an http.post using http module via browser on localhost: when I check the response headers from the remote server, I see there are no "set-headers" with cookie values, only:
Content-Type application/json;charset=utf-8
If I send a post request via Node, Postman o cURL these are the response headers:
Connection keep-alive
Access-Control-Allow-Origin *
Set-Cookie JSESSIONID=wl6sCW6uT_9bAgoOSj9YtgfJvYGxF6XrNjH22YFm.srv79627; path=/
Server WildFly/10
Content-Type application/json;charset=utf-8
Content-Length 352
Date →Tue, 12 Mar 2019 22:33:25 GMT
In Vue app I receive
In the console developer I see in the tab application->cookies only one cookie saved on localhost.
Is this related to browser limitation? Any workaround?
I need to keep track of the value in set header from remote server for session management.
This is the actual code:
const options = {
hostname: 'XX.XX.XX',
port: 8080,
path: '/myurlsearch_2?searchText='+mess +'&user=&pwd=&ava=XXX',
method: 'POST',
rejectUnauthorized: false,
headers: {
'Cookie': this.$session.exists('JSESSIONID=') ? this.$session.get('JSESSIONID=') :''
// 'Access-Control-Allow-Credentials:true' -> this won't work
}
Thanks in advance

Office add-in: XMLHttpRequest cannot load XXX due to access control checks

I'm building an Outlook add-in with jQuery and the Office JS API. I have a local server going while developing, and I'm trying to submit a POST request to an endpoint on my site's main server. Every time I try to submit the request, I get the following three errors:
Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin
XMLHttpRequest cannot load https://myurl.com/my_endpoint due to access control checks
Failed to load resource: Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin
What I've done so far:
Found this related thread: HTTP fetch from within Outlook add-ins
The only answer says to do three things:
Make the request with XMLHttpRequest. Yup, did that:
function submitForm(var1, var2) {
var http = new XMLHttpRequest();
var params = 'var1=' + encodeURIComponent(var1) + '&var2=' + encodeURIComponent(var2);
http.open("POST", 'https://myurl.com/my_endpoint', true);
http.setRequestHeader('Access-Control-Allow-Origin', 'https://localhost:3000');
http.setRequestHeader('Access-Control-Allow-Credentials', true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {
console.log("response:", http.responseText);
console.log("status:", http.status);
};
http.send(params);
}
Add the service URL into the manifest's AppDomains list. Yup, did that, too. This is from my manifest.xml:
<AppDomains>
<AppDomain>https://myurl.com</AppDomain>
<AppDomain>https://myurl.com/my_endpoint</AppDomain>
<AppDomain>https://localhost:3000</AppDomain>
</AppDomains>
Use only services which are under SSL connection. Yup, the myurl.com server is only accessible via SSL.
I also found this documentation (https://learn.microsoft.com/en-us/office/dev/add-ins/develop/addressing-same-origin-policy-limitations) that recommends to solve this with cross-origin-resource-sharing (CORS), and points to this link: https://www.html5rocks.com/en/tutorials/file/xhr2/#toc-cors
So, I checked the server set-up for https://myurl.com and I am in fact allowing requests from any origin. UPDATE 1: as an example, here's what the output of a successful network request to https://myurl.com/my_endpoint looks like (notice the Accept: */* header):
Request URL: https://myurl.com/my_endpoint
Request Method: POST
Status Code: 200 OK
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-cache, no-store, must-revalidate, public, max-age=0
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Expires: 0
Pragma: no-cache
Server: nginx/1.10.3 (Ubuntu)
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 52
Content-type: application/x-www-form-urlencoded
Host: myurl.com
Origin: chrome-extension://focmnenmjhckllnenffcchbjdfpkbpie
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
var1: var1
var2: var2
Plus, another thing leading me to believe the problem isn't with https://myurl.com is: when I open my network tab in my debugger, I can see that my request never reaches https://myurl.com. I'm also not seeing the request pings in my https://myurl.com server logs. This is the output of my network request when I try to ping https://myurl.com from the Outlook add-in:
Summary
URL: https://myurl.com/my_endpoint
Status: —
Source: —
Request
Access-Control-Allow-Origin: https://localhost:3000
Access-Control-Allow-Credentials: true
Content-Type: application/x-www-form-urlencoded
Origin: https://localhost:3000
Accept: */*
Referer: https://localhost:3000/index.html?_host_Info=Outlook$Mac$16.02$en-US
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko)
Response
No response headers
Request Data
MIME Type: application/x-www-form-urlencoded
var1: var1
var2: var2
Any recommendations for what else I need to change to enable making a POST request to myurl.com? Thanks in advance to the kind soul that helps me figure this out.
UPDATE 2: For what it's worth, I haven't done any configs to my node server beyond what came out-of-the box when I ran npm install -g generator-office. E.g. I haven't touched these two files:
.babelrc
{
"presets": [
"env"
]
}
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
polyfill: 'babel-polyfill',
app: './src/index.js',
'function-file': './function-file/function-file.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.html$/,
exclude: /node_modules/,
use: 'html-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: 'file-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
chunks: ['polyfill', 'app']
}),
new HtmlWebpackPlugin({
template: './function-file/function-file.html',
filename: 'function-file/function-file.html',
chunks: ['function-file']
})
]
};
Failed to load resource: Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin
The server responds to your pre-flight request (usually OPTIONS) and does not allow to get a response, that's because your origin localhost:3000 is not allowed on server side.
You need to respond to OPTIONS on server with 204 status code and a header like:
Access-Control-Allow-Origin 'localhost';