Calvin Goodale, Developer - Blog
c g o o d a a l e . . c o m

Obfuscating file paths

While working on the cloud storage app this week, I was faced with a challenge where I needed the files on the server to be available to users for file previews and downloads, but I did not want to file path to be visible to the users - this way a user could not just save the file path and retain access to the files even after a share expired, for example.

I also needed to prevent users without the proper permissions or file ownership from downloading and viewing the files, for obvious reasons.

There are a few solutions to this challenge - one of them being that the files could be stored outside of the web root, which would prevent direct access to them via the browser. Another possible solution would be to use .htaccess to prevent direct access to specific paths containing the files. Because the files were already being stored inside the document root, I decided to go with the .htaccess method.

The roadblock I faced using the .htaccess method was that I still needed external users to be able to access the files using a pin, so I couldn't easily block all un-authenticated users from accessing the file paths. I'm sure there are some ways of handling authentication using the .htaccess file, but I believed there was another solution so I kept digging.

The solution I eventually settled on was to have file requests be routed through a php file that checks if the user is authenticated with the proper permissions to view the file, and then uses fopen to output the file to the browser.

Now, instead of using the actual server file path for my <img> src, I can do something like this:

<img id="img-preview" src="get_file.php?id=75">

Which will then make a call to my php file with the following code:

if ($IsAuthenticated  && is_readable($FilePath)) {
   header("Content-Type: ".mime_content_type($FilePath));
   $handle = fopen($FilePath,"r");
   fpassthru($handle);
   fclose($handle);
   exit; 
} else {
   http_response_code(403);
   echo "Unauthorized";
   exit;  
}

This allowed me to use the .htaccess file to block direct access to the actual file paths without affecting external users accessing the files with a pin.


0 Comments

Calculating menu position

I came across a front-end challenge last week that I found interesting. One of the features of the cloud storage app I am building at work is a drop-down menu that appears when clicking on a triangle in the top right of a folder or file icon:

The issue was that if the element clicked is too close to the left or right edge of it's container, the dropdown menu would either be covering the sidebar (left side) or cutoff by the viewport (right side).

To solve this, I had to use some math to calculate the available space and position of the clicked element and then set the position of the dropdown based on these factors.

I decided to use the total width of the container and compare it to the center of the clicked element and then position the dropdown a percentage to the left or right of the clicked element based on these datapoints.

I first calculated the center of the clicked element compared to it's contaner and the center of the container itself (I had to subtract 250 from both due to the left sidebar having a width of 250px and a fixed position):

var parentCenter = $(this).parent().offset().left + 60 - 250;
var windowCenter = ($(window).width() - 250) / 2;

Then I calculated the offset of the clicked element's center from the window center, and then used that number to calculate the offset I needed from the parent element's center (I needed the dropdown container to be offset left or right relative to the clicked element the same percentage that the parent container is offset from the total width of their parent container):

var percentageFromCenter = (parentCenter / windowCenter);
var offset = 120 - (120 * percentageFromCenter);

Last step was setting the margin-left of the dropdown container to that offset before toggling it's display:

$(this).parent().find('.file-icon-dropdown').css('margin-left', offset);

The result can be seen here (apologies for the text url, apparently imgur converts all gifs to mp4 files now and my WYSIWYG editor doesn't allow embedded video files):

https://i.imgur.com/gHKf7OE.mp4


0 Comments

Creating a cloud storage app

My current task at work is to build out a cloud storage app with a PHP backend, which will be used for sharing documents both internally and with externally. Necessary features:

  • User registration, authentication
    • User roles: Admin User, Internal User, External User
  • Folder creation, copy, share, delete
  • File upload, download, coopy, share, delete
    • File previews
    • File details
  • Search functionality

I started out by creating a DB diagram for the mysql database:

There will likely be additions to the database structure as the app gets more fleshed out, but this will be a good initial design and will allow me to start fleshing out the most critical front end and back end features.


0 Comments