WHMCS API error when calling "OpenTicket" - whmcs

I am trying to create a ticket via the WHMCS Api (latest version) using axios from my react app.
When I make the call, there are two calls from the client: one for the OPTIONS (CORS) and the second for the actual POST, with all the the necessary fields, however, I am getting two errors:
1. Request one:
Request URL: https://my-domain/includes/api.php?accesskey=<KEY>q&identifier=<ID>&secret<SECRET>&action=OpenTicket
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: 62.*.*.*:443
Response:
result=error;message=An admin user is required
2. Request 2:
Request URL: https://my-domain/includes/api.php?accesskey=<KEY>q&identifier=<ID>&secret<SECRET>&action=OpenTicket
Request Method: POST
Status Code: 200 OK
Remote Address: 62.*.*.*:443
Payload:
{
admin: true
deptid: "1"
email: "something#mail.domain"
markdown: true
message: "test"
name: "text"
priority: "Medium"
responsetype: "json"
subject: "test"
}
Response:
result=error;message=Name and email address are required if not a client
JS code:
...
const ticketObject = {
admin: true
deptid: "1"
email: "something#mail.domain"
markdown: true
message: "test"
name: "text"
priority: "Medium"
responsetype: "json"
subject: "test"
};
const res = await axios.post(
"https://my-domain/includes/api.php?accesskey=<KEY>q&identifier=<ID>&secret<SECRET>&action=OpenTicket",
ticketObject
);
...
Server details:
OS: CentOS 7
Webserver: Nginx (latest version) proxy_pass to httpd
Nginx conf:
server {
server_name my-domain www.my-domain;
error_log /var/log/httpd/domains/my-domain.error.log error;
location / {
location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|htm|html|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
root /home/admin/web/my-domain/public_html;
access_log /var/log/httpd/domains/my-domain.log combined;
access_log /var/log/httpd/domains/my-domain.bytes bytes;
expires max;
try_files $uri #fallback;
}
# Check if the origin of th request
set $cors '';
if ($http_origin ~* (https?://.*\.proudtech\.ro?(:[0-9]+)?$)) {
set $cors 'on';
}
if ($request_method = OPTIONS) {
set $cors "${cors}_options";
}
# Allow CORS on preflight request
if ($cors = 'on_options') {
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
return 204;
}
# Proxy pass to upstream
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
# Allow CORS on other requests after returning from the upstreams
if ($cors = 'on') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
}
proxy_pass http://62.*.*.*:8080;
}
location /error/ {
alias /home/admin/web/my-domain/document_errors/;
}
location #fallback {
proxy_pass http://62.*.*.*:8080;
}
include /home/admin/conf/web/nginx.my-domain.conf*;
}
server {
if ($host = my-domain) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 62.*.*.*:80;
server_name my-domain www.my-domain;
return 404; # managed by Certbot
}
VirtualHost conf:
ServerName my-domain
ServerAlias www.my-domain
ServerAdmin info#my-domain
DocumentRoot /home/admin/web/my-domain/public_html
ScriptAlias /cgi-bin/ /home/admin/web/my-domain/cgi-bin/
Alias /vstats/ /home/admin/web/my-domain/stats/
Alias /error/ /home/admin/web/my-domain/document_errors/
#SuexecUserGroup admin admin
CustomLog /var/log/httpd/domains/my-domain.bytes bytes
CustomLog /var/log/httpd/domains/my-domain.log combined
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
ErrorLog /var/log/httpd/domains/my-domain.error.log
<Directory /home/admin/web/my-domain/public_html>
AllowOverride All
Options +Includes -Indexes +ExecCGI
php_admin_value open_basedir /home/admin/web/my-domain/public_html:/home/admin/tmp
php_admin_value upload_tmp_dir /home/admin/tmp
php_admin_value session.save_path /home/admin/tmp
</Directory>
<Directory /home/admin/web/my-domain/stats>
AllowOverride All
</Directory>
<IfModule mod_ruid2.c>
RMode config
RUidGid admin admin
RGroups apache
</IfModule>
<IfModule itk.c>
AssignUserID admin admin
</IfModule>
IncludeOptional /home/admin/conf/web/httpd.my-domain.conf*

See this documentation about the OpenTicket API function: https://developers.whmcs.com/api-reference/openticket/
You shouldn't both use admin and email. Email should only be entered if it's a non-existing client that creates the ticket. You shouldn't use name either.

Related

Apache2 config to Nginx config?

I have 2 ports running on my server right now.
that is the main application port 5455
socket port 8433
we are migrating this apache setup to Nginx.
In Apache, we had 2 conf files 1 for the application server and 1 for the socket
I have been able to move the application server correctly but not able to make the socket work
<VirtualHost _default_:8443>
ServerAdmin admin#abc.tech
ServerName api.abc.tech
DocumentRoot /var/www/api.abc.tech/socket
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:8000/$1 [P,L]
ProxyPass /socket.io/ http://127.0.0.1:8000/socket.io/
ProxyPassReverse /socket.io/ http://127.0.0.1:8000/socket.io/
SSLCertificateFile /etc/apache2/sites-available/api.abc.tech.crt
SSLCertificateKeyFile /etc/apache2/sites-available/api.abc.tech.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</VirtualHost>
My current Nginx file is as below
server {
listen 8443;
server_name _;
location / {
proxy_pass http://localhost:8443;
}
}
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/api.abc.tech/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.abc.tech/privkey.pem;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name api.abc.tech;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:5455;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 200;
}
}
location ^~ /.well-known/acme-challenge/ {
allow all;
}
}
so when the application hits the below route
https://api.abc.tech:8443/socket.io/?EIO=3&transport=polling&t=MvOh2
it is returning below error
Referrer Policy: no-referrer-when-downgrade
If you need any other information please feel free to ask
Any assistance on this will be highly appreciated.

Nginx is not proxying to the node backend

I have react application running on Nginx and backend application on Nodejs(running on another port 8080) with routes of patterns "/org-metadata/**, /proxy-api/**, /node-api/**".
I am trying to proxy the nginx to nodejs running on 8080, but it does not reach the backend. and the nginx gives the 503 Service Unavailable response and some times response 200 with You need to enable JavaScript to run this app.
Can some one pls point where am I missing anything?
Below is my nginx.conf file :
worker_processes auto;
events {
worker_connections 8000;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
# listen on port 80
listen 80;
# where the root here
root /var/www;
# what file to server as index
index index.html index.htm;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
try_files $uri $uri/ /index.html;
}
# Javascript and CSS files
location ~* \.(?:css|js)$ {
try_files $uri =404;
expires 1y;
access_log off;
add_header Cache-Control "public";
}
location ~ (proxy-api|org-metadata|node-api) {
try_files $uri #nodejs;
}
location #nodejs {
proxy_pass http://nodejs:8080;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
}
}
}

Nginx redirects to first Subdomain when accessing second

So here's my situation: I have a Nextcloud and OpenHAB set up on my server and want to access both from outside my local network. I use Nginx as my reverse proxy to access my nextcloud on cloud.foo.bar and my openHAB on home.foo.bar. This works for my cloud, however if I access home.foo.bar, I either get redirected to cloud.foo.bar (on my Windows 10 machine) or just access my nextcloud under the home.foo.bar domain. Here's my nginx config (sites-available/default).
server {
listen 80;
server_name home.foo.bar;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
upstream php-handler {
#server 127.0.0.1:9000;
server unix:/var/run/php/php7.2-fpm.sock;
}
server {
if ($host = cloud.foo.bar) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name cloud.foo.bar;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.foo.bar;
ssl_certificate /etc/letsencrypt/live/cloud.foo.bar/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cloud.foo.bar/privkey.pem; # managed by Certbot
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this
# topic first.
# add_header Strict-Transport-Security "max-age=15768000;
# includeSubDomains; preload;";
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Path to the root of your installation
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
# last;
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php$request_uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff|svg|gif)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
}
I only have an A record for the ipv4 of the server for #foo.bar, I tried using two records for cloud.foo.bar and home.foo.bar pointing towards the same ipv4, which didn't change anything.
I seem to answer a lot of my question just after posting them myself... I had to add a redirect for https requests, as my configurations forwareded all requests on port 80 to port 443 which only has a listener for cloud.foo.bar.

CORS rules coversion from Apache .htaccess to nginx

Presently I have these .htaccess rules working perfectly on my Apache server:
<IfModule mod_headers.c>
SetEnvIf Origin "https://(www\.)?(domain.com|beta.domain.com|domain.loc)$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, X-XSRF-TOKEN"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Credentials true
</IfModule>
<IfModule mod_rewrite.c>
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
Recent decision to switch to nginx requires us to implement the same. I'm still getting a hang of its internals and really need help converting this into its nginx config counterpart.
EDIT: What I tried so far:
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
server_name api.mydomain.loc;
root /var/www/mydomain/api/public;
index index.html index.htm index.php;
location / {
if ($http_origin ~* https://(www\.)?(mydomain.loc)) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, X-XSRF-TOKEN";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Credentials true;
}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Help would be greatly appreciated.
The simplest nginx equivalent of the Apache config in the question would be, just use add_header and wrap it all in anif block that does a regex match against $http_origin:
location / {
if ($http_origin ~* https://(www\.)?(domain.com|beta.domain.com|domain.loc)) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, X-XSRF-TOKEN";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
add_header Access-Control-Allow-Credentials true
}
# use $http_authorization to get the value of the Authorization request header
}
The extra RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] stuff that you need to do with Apache isn’t necessary with nginx; instead just use $http_authorization.
Note that variables in nginx that have names prefixed with $http_ are special variables:
$http_name
arbitrary request header field; the last part of a variable name is the field name
converted to lower case with dashes replaced by underscores
Thus $http_origin gives you the value of the Origin request header, $http_authorization gives you the value of the Authorization request header, etc.

Force MP3 File to download rather then streaming

I have some mp3 files in different directories other than root directory.
When users click on the links to mp3, instead of downloading it starts streaming in most browsers (mostly in mobile browsers).
I have tried adding the below code in the .htaccess, but no luck
<FilesMatch "\.(?i:mp3)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
My server is build in apache and nginxcp (nginx admin). Can anyone help me out?
EDIT: Below is the edited file for my domain vhost file. But after i rebuild host and restart nginx, the file change to its original one and the code "location ~ .mp3$ { add_header Content-Disposition attachment; }" becomes disappears.
server {
error_log /var/log/nginx/vhost-error_log warn;
listen 198.xxx.xx.xxx:80;
listen [::]:80;
server_name dl.xxxx.com www.dl.xxxx.com;
access_log /usr/local/apache/domlogs/dl.xxxx.com-bytes_log bytes_log;
access_log /usr/local/apache/domlogs/dl.xxxx.com combined;
root /home/xxxx/public_html/download;
#location / {
location ~*.*\.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|html|htm|txt|js|css|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
expires 1M;
try_files $uri #backend;
}
location / {
error_page 405 = #backend;
add_header X-Cache "HIT from Backend";
proxy_pass 198.xxx.xx.xxx:8081;
include proxy.inc;
include microcache.inc;
}
location #backend {
internal;
proxy_pass http://198.xxx.xx.xxx:8081;
include proxy.inc;
include microcache.inc;
}
location ~ .*\.(php|jsp|cgi|pl|py)?$ {
proxy_pass http://198.xxx.xx.xxx:8081;
include proxy.inc;
include microcache.inc;
}
location ~ /\.ht {
deny all;
}
location ~ \.mp3$ { add_header Content-Disposition attachment; }
}