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

Hack Reactor | BOC | Journal Entry 2

Overview
Creating the ArtistProfile component for the SoundCrate app

Challenge/Motivation
This component will show a user's profile picture, name, a short bio, and will map over the user's tracks and display them below. If a user is looking at their own profile, it will also have an edit button, allowing the user to navigate to the view for updating and editing their profile.

Actions Taken
When the skeleton for this component had been created, it was being rendered directly in the the other components that needed access to it. Because we decided to have the main App component handle all of the conditional rendering for any "main" view (view that takes up the full page, minus the TopBar and NavBar) I decided to move the component outside of the components that were rendering it separately.

Because there was also another component being rendered similarly (the Play component that displays for the user to listen to a track) I moved them both up to the App component simultaneously.

To do so, I had to create useState variabels in the App component for both artistData and songData as well as the setSongData and setArtistData functions. I also had to create handler functions that would be passed down to the child components (such as any view that is showing a SongCard where the user can click on an artist name or a song name) to allow them to pass data back up to the state here in App upon clicking a related link.

Results Observed
I believe a structure where the main App component houses most of the necessary data and functions and then passes it down to the child components is the cleanest way to handle the rendering and data of the main views. I'm looking forward to the database-related stuff being finished so we can start to use the actual database data in our components, and I think it will allow us to more easily develop the components we are responsible for.


0 Comments

Hack Reactor | BOC | Journal Entry 1

Overview
Researching and creating a custom theme with Material UI

Challenge/Motivation
The app our team was tasked with building is SoundCrate, which is a TikTok-esque audio recording and collaboration app. It needs to have cohesive component style and structure based on the wireframe and requirements of the client, and we decided to use Material UI for rapid development.

Actions Taken
I started by doing some research on Material UI and theming best practices, and put together a palette based on our initial Proto.io design. Although our initial palette and styles may change as we iteratively develop the app, having a theme will allow us to do so easily from the top-down, as opposed to going back and changing the CSS in multiple places.

Currently, our custom theme has both a primary and secondary color (with light, main, and dark variations), a default font and text color, a default and secondary background color, an error color, as well as two different variations of body text.

Brian and I also put together some documtentation related to the types of MUI components we will likely want to use for our component, along with some basic instructions on how to utilize the theme attributes in our inline styling.

I also put together a ThemeExample component so our team can see what the various theme colors and fonts look like in the browser and how to use them in our code:

Results Observed
I've learned a ton about Material UI over the past few sessions, and I think having a theme in place and ready to use will make development more efficient and will allow each team member to focus on the important pieces of their components instead of having to worry too much about CSS and HTML during development.


0 Comments