yii2 can not read json file into backend/web folder - json

I have js file in backend/web/js/my.js
var conf = function() {
return ('../conf.json');
}
But can not read conf.json file. I got 403 error. What is the problem ?
Thanks anyway

you should use
var conf = function() {
return ('../js/conf.json');
}
or build the proper url using urlHelper
<?= 'var url_base = "' . \yii\helpers\Url::base() .'";'; ?>
var conf = function() {
return ( url_base + '/js/conf.json');
}

you need add some row in .htacces file into the root
#if files in the root
RewriteRule conf.php conf.php [L]
#or
RewriteRule conf.json conf.json [L]
#if files in the directory into the root
RewriteRule ^js/(.*)$ js/$1 [L]
#or images directory
RewriteRule ^images/(.*)$ images/$1 [L]

Related

How can I prevent direct access to files using the .htaccess file?

I have a problem, I tried to restrict access to files with direct link (etc. www.domen.com/folder/subfolder/file.ext), to can only access to them using HTML code like "< img src ='/folder/subfolder/file.ext' >"...
I create .htaccess file with next lines
# enable mod_rewrite
RewriteEngine On
# RewriteCond = define rule condition
# HTTP_REFERER = check from where the request originated
# ! = exclude
# ^ = start of string
# [NC] = case insensitive search
RewriteCond %{HTTP_REFERER} !^http://domen.com/folder/subfolder [NC]
# \ = match any
# . = any character
# () = pattern, group
# $ = end of string
# [F] = forbidden, 403
# [L] = stop processing further rules
RewriteRule \.(gif|jpg|jpeg|png|mp4|mov|mkv|flv)$ - [F,L]
Permission code of my files is 0644 in folders and subfolders, and permission code of my folders and subfolders is 0755
Problem is next.. When I use this code in .htaccess file I restrict direct access to files but at the same time I cant access them with HTML code..
<Directory platform/courses/*>
Order Allow,Deny
Allow from 1.1.1.1
Deny from All
</Directory>
<Directory>
Order Allow, Deny
Allow from All
</Directory>
I tried something like this (with IP addres taken from my cPanel) but I get this result:
This is a cutdown version of what I use, so may have syntax errors.
The code is laid out to demonstrate the process. It can be made more robust.
The user is shown a url with a filename using download.php.
This can be posted.
Once the page is shown, it saves the filename with an expiry of 1 hour
in the cookie. If it expires, the page has to be refreshed.
When the button is pressed, sendfile.php gets all the information
from the cookie, validates the expiry and filename and sends it.
download.php
This is the landing page that the user can link to.
Show the user a link like /download/document.pdf
Use .htaccess to map it to /download?name=document.pdf
<?php
// Returns the param by name, if not found then get it from the current_url.
// So this works regardless of how the .htaccess redirection has been done.
function Get_Param ($name, $current_url)
{ $par = filter_var ($_GET [$name] ?? '', FILTER_SANITIZE_STRING);
if ($par)
{return $par;}
if ($only)
{return '';}
$pi = pathinfo ($current_url);
$pi = $pi['filename'] ?? '';
if (strpos ($pi, '=') == 0)
{return $pi;}
else
{return '';};
}
//Save Information in session with an expiry of 1hr
function Save_Info ($file)
{ $expiry = time()+3610;
setcookie ('Download',$file, $expiry, '/');
}
//Get the Filename from the param or url
$file = Get_Param ('name', $current_url);
//Save to Session
Save_Info ($file)
// Show page with filename and details
// Show button with link "/sendfile"
?>
sendfile.php
This basically pretends to be the file thats being downloaded and then dies.
<?php
// Sends the file and dies
function Send_File ($file)
{ header ('Content-Description: File Transfer');
header ('Content-Type: application/octet-stream');
header ('Content-Disposition: attachment; filename="'.basename($file).'"');
header ('Expires: 0');
header ('Cache-Control: must-revalidate');
header ('Pragma: public');
header ('Content-Length: ' . filesize($file));
flush ();
if (readfile ($file)) {
//LogIt ($file);
}
die ();
}
//Load Info from session and unset it
function Load_Info ()
{ $file = $_COOKIE ['Download'] ?? '';
unset ($_COOKIE ['Download']);
return $file
}
//Validate FileName
function Is_Valid ($file,$path)
{ if (!$file) {
return 'FileName is Blank';
}
$file = urldecode($file);
if (!preg_match('/^[^.][-a-z0-9_.]+[a-z]$/i', $file)) {
return 'Invalid FileName';
}
if (!file_exists($path.$file)) {
return 'File does not exist';
}
return false;
}
//Your actual path to the file
$path ='';
// Load Info from Session
$file = Load_Info ();
// Die if filename invalid or session expired
$error = Is_Valid ($file,$path);
if (!$error) {
//Show Message and die
}
else
{Send_File ($path.$file);
}
?>

Callback URL not receiving JSON data

I have a PHP page that receives JSON responses located at https://example.ac.ke/op/api/mypesa/index.php
I have success posting responses using Postman when I post to either
https://example.com/op/api/mypesa/
or
https://example.com/op/api/mypesa/index.php
but not when I post to
https://example.com/op/api/mypesa
I have tried redirecting and adding trailing / in htaccess in vain.
I need to make https://example.com/op/api/mypesa to be my callback URL. When I post the receiving page is called but it seems like the data is not redirected.
NEED HELP REDIRECTING BOTH PAGE AND POST DATA
Since I have success redirecting page but not the data
My .htaccess has the following content
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>
Posting using postman
database table receiving the json data from page
Posting using postman to the page
Content of my index file located in mypesa folder
<?php
require 'config.php';
header("Content-Type: application/json");
$response = '{
"ResultCode": 0,
"ResultDesc": "Confirmation Received Successfully"
}';
$mpesaResponse = file_get_contents('php://input');
$logFile = "M_PESAConfirmationResponse.txt";
$jsonMpesaResponse = json_decode($mpesaResponse, true);
$transaction = array(
':TransactionType' => $jsonMpesaResponse['TransactionType'],
':TransID' => $jsonMpesaResponse['TransID'],
':TransTime' => $jsonMpesaResponse['TransTime'],
':TransAmount' => $jsonMpesaResponse['TransAmount'],
':BusinessShortCode' => $jsonMpesaResponse['BusinessShortCode'],
':BillRefNumber' => $jsonMpesaResponse['BillRefNumber'],
':InvoiceNumber' => $jsonMpesaResponse['InvoiceNumber'],
':OrgAccountBalance' => $jsonMpesaResponse['OrgAccountBalance'],
':ThirdPartyTransID' => $jsonMpesaResponse['ThirdPartyTransID'],
':MSISDN' => $jsonMpesaResponse['MSISDN'],
':FirstName' => $jsonMpesaResponse['FirstName'],
':MiddleName' => $jsonMpesaResponse['MiddleName'],
':LastName' => $jsonMpesaResponse['LastName']
);
$log = fopen($logFile, "a");
fwrite($log, $mpesaResponse);
fclose($log);
echo $response;
insert_response($transaction);
?>

Can't resolve target of expression 'str_replace('\\', '/', realpath(dirname(__FILE__)))/system/initialize.php'

This is what I have in my config file:
define('BASE_DIR', str_replace('\\', '/', realpath(dirname(__FILE__))) . '/', false);
// output: C:/xampp/htdocs/myweb/
define('BASE_URL', $protocol . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['SCRIPT_NAME']), '/.\\') . '/', false);
//output: http://localhost/myweb/
define('APP_DIR', BASE_DIR . 'app/', false);
// output: C:/xampp/htdocs/myweb/app/
define('TEMP_DIR', BASE_DIR . 'app/view/template/', false);
//output: C:/xampp/htdocs/myweb/app/view/template/
define('LIBRARY_DIR', BASE_DIR . 'library/', false);
//output: C:/xampp/htdocs/myweb/library/
define('SYSTEM_DIR', BASE_DIR . 'system/', false);
//output: C:/xampp/htdocs/myweb/system/
I include the above file in my index file and then include a file initialize.php like
index.php
// Include the config file. If file not found throw error and exit.
if (!file_exists('config.php')) {
header('Location: error/404.php');
exit();
} else {
include_once 'config.php';
}
// Load startup file to check, set environment plus a few core files
require_once SYSTEM_DIR . 'initialize.php';
The initialize.php conducts a few checks and sets a few parameters required by the application.
This works fine but recently I switched to PhpStorm and the IDE says
Can't resolve target of expression 'str_replace('\\', '/', realpath(dirname(__FILE__)))/system/initialize.php' (at line 27).
What is this problem? and if the target of expression isn't resolved, as per the IDE, how is it still including the initialize file.
The warning you see is just an IDE warning, it doesn't cause any problem. The IDE can not get to know what files you want to include because the expression is too complicated.
IDE usually scans all PHP files in your project. so even if the include/require are not parsed correctly, the IDE still knows all the classes/functions in all your PHP files.

Number of times a file (e.g., PDF) was accessed on a server

I have a small website with several PDFs free for download. I use StatCounter to observe the number of page loads. It also shows me the number of my PDF downloads, but it considers only those downloads where a user clicks on the link from my website. But what's with the "external" access to the PDFs (e.g., directly from Google search)? How I can count those? Is there any possibility to use a tool such as StatCounter?
Thanks.
.htaccess (redirect *.pdf requests to download.php):
RewriteEngine On
RewriteRule \.pdf$ /download.php
download.php:
<?php
$url = $_SERVER['REQUEST_URI'];
if (!preg_match('/([a-z0-9_-]+)\.pdf$/', $url, $r) || !file_exists($r[1] . '.pdf')) {
header('HTTP/1.0 404 Not Found');
echo "File not found.";
exit(0);
}
$filename = $r[1] . '.pdf';
// [do you statistics here]
header('Content-type: application/pdf');
header("Content-Disposition: attachment; filename=\"$filename\"");
readfile($filename);
?>
You can use a log analyzer to check how many times a file was accessed. Ask you hosting provider if they provide access to access logs and a log analyzer software.
in php, it would be something like (untested):
$db = mysql_connect(...);
$file = $_GET['file'];
$allowed_files = {...}; // or check in database
if (in_array($file, $allowed_files) && file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
mysql_query('UPDATE files SET count = count + 1 WHERE file="' . $file . '"')
readfile($file);
exit;
} else {
/* issue a 404, or redirect to a not-found page */
}
You would have to create a way to capture the request from the server.
If you are using php, probably the best would be to use mod_rewrite.
If you are using .net, an HttpHandler.
You must handle the request, call statcounter and then send the pdf content to the user.

nginx: location condition + secure_link

I have a hard time figuring out the correct configuration.
I have an URL - e.g.
http://example.com/[md5-checksum]/[num-value-1]/[num-value-2]/[file-name]
http://example.com/ac64392dba67d618ea6a76843c006708/123/56789/test.jpg
I want to make sure that the md5-checksum matches salt + num-value-2. So the file name and num-value-1 should be ignored (only needed for the filename header) in order to build the md5 checksum.
Following configuration does not result in what I want to achieve.
location ~* ^/download/([a-zA-Z0-9]+)/([0-9]+)/([0-9]+)/(.*)$ {
secure_link $3;
secure_link_md5 segredo$3;
if ($secure_link = "") {
return 500;
}
set $filename $4;
add_header Content-Disposition "attachment; filename=$filename";
rewrite ^/download/([a-zA-Z0-9]+)/([0-9]+)/([0-9]+)/(.*)$ /$2/$3 break;
}
I appreciate any help!
secure_link $3
should have been
secure_link $1