Resolve filesystem paths (possibly with symlinks) with Node.js - node.js

I need a way to verify whether or not a file is under a specific path. If the path is /var/www and the file is /var/www/something/something-else/file, I need to return true. If the file is /var/www/../../etc/passwd, I need to return false.
In PHP land, I usually use a function called realpath():
realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input path and returns the canonicalized absolute pathname.
I run realpath() on both the desired path and the full file path, then determine if the desired path is a substring of the result of the fully resolved file path. If it is, I return true.
Is there a function for Node.js that achieves the same goal? path.resolve() gets me half way, but doesn't handle any symlinks that are actually in the filesystem. fs.readlink() has absolutely no documentation at all, and may not directly apply since I won't always have symlinks.
Must I loop through each part of the path, resolving symlinks as I go, or is there a more canonical method?

Node also has fs.realpath() so that should work the same way as in PHP.

Related

How to determine if file system path is directory or file?

I'm looking to determine if a file system path is directory or file. I'm not looking to checking for the type an existing path. I'm trying to determine if the path function argument string is a referring to a directory or file.
How do I make a distinction between a file and a directory when this:
/Users/thomas/Desktop/node
The following path could refer to a directory node, or a file node without an extension.
I was thinking about using a trailing / to connote directory.
So this would mean a directory:
/Users/thomas/Desktop/node/
And this would mean a file:
/Users/thomas/Desktop/node
However node's path methods like .resolve() and .join() do not take into consideration the trailing / and always remove it. So is this good practice?
There is no way to check if an arbitrary string is a directory or file if it does not exist.
However for existing paths, you can use fs.stat() on the path, which will give you an object that has methods for checking the path type (e.g. isDirectory(), isFile(), etc).

ENOENT no such file on Express Endpoint for readFileSync

I've been going slightly crazy trying to figure this out. I have some certs that I need to pass through to an authentication client from my api; however, the application continues to throw ENOENT exceptions even though the file clearly exists within the same directory (I've fiddled with this to make sure). I'm using readFileSync, effectively doing the following:
key: fs.readFileSync('./privateKey.pem'),
Strangely, if I run this on a standalone Node server not as a part of an api, the file is able to be found without a problem. Is there some consideration I'm not aware of when trying to use readFileSync in such a scenario?
Thanks!
In node you need to be very careful with relative file paths. The only place where I'd ever really use them is in require('./_____') statements, where ./ to mean "relative to this file". However, require is kind of a special case because it is a function that node automatically creates per-file, so it knows the path of the current file.
In general, standard functions have no way of knowing the directory containing the script that happened to call a function, so in almost all cases, ./ means relative to the current working directory (the directory you were in when you ran node <scriptname>.js). The only time that is not the case is if your script or a module you use explicitly calls process.chdir to set the working directory to something else. The correct way to reference files relative to the current script file is to explicitly use an absolute path by using __dirname + '/file.js'.

Node.js path.join removes leading period

I came home with a work project that I planned on fiddling with on my personal computer, I installed everything, using the exact same environment (Node v0.11.12), etc. Start the project, then I'm greeted with messages complaining that the config loader module cannot locate a file (that exists and is at the path exposed by the error).
Looking closer at the error, I realize that the problem is path.join(). Where
path.join('./foo/bar');
// 'foo/bar'
Which is not good. Why does path.join remove the leading period?
** Note **
The above is simply an example. The program make use of the function like
var configFile = require(path.join(modulePath, 'conf', file));
for example, where modulePath is relative to the current working directory (i.e. ./app/module/)
This is correct behavior, and is documented in the Path.join documentation:
Join all arguments together and normalize the resulting path.
It is correct because foo/bar is the normalized (canoncial) form of ./foo/bar, just as it is the normalized form of ./foo/././bar/. or foo/baz/../bar.
(Differences between require('./foo/bar') and require('foo/bar'), and any resulting problems of such, should be specifically addressed in a different question without path.join.)

Comparing path names, and the path may be non-existent

I am trying to write a file blacklist kernel module for school. In this module I need to compare paths names from intercepted system calls(which can be relative or absolute) to a list of blacklisted path names(which are all absolute). These paths may or may not exist at the time the module is loaded. I have been told to look at the system calls in /fs/open.c for getting a struct path. I tried user_path but it returns an error if the path is non-existent. Any help would be appreciated.
Edit: Also, I am on the 3.0.4 kernel. I have the strings for blacklisted path names read from the file (yeah I know its bad but this is the way they want it done) and inserted into the internal list. I am just stuck on the comparison of the blacklist path name and path name/file name passed to the intercepted system calls.

Best practice for making code portable for domains, subdomains or directores

I recently coded something where it wasn't known if the end code would reside in a subdomain (http://user.domain.com/) or in a subdomain (http://domain.com/user), and I was lost as to the best practice for these unknown scenarios. I could thinks of a couple:
Use absolute paths (/css/styles.css) and modrewrite if it ends up being /user
Have a settings file and declare a variable with the path (<? php echo $domain . "/css/styles" ?>)
Use relative paths (../css/styles.css).
What is the best way to handle this?
If there is any question about where something might be deployed, I would avoid absolute paths whenever possible, and if you must use them, make sure to construct them using the data in the $_SERVER superglobal. The value $_SERVER['PHP_SELF'] will contain the path and filename to the currently executing script, and you can then extract the path using something like:
$path = dirname($_SERVER['PHP_SELF']);
Likewise, the value $_SERVER['HTTP_HOST'] will contain the current host, and from those two together you can build the path to wherever you are. If you're using HTTPS you may also need to check the protocol in $_SERVER['HTTPS'].
With that said, it is still best to use relative paths and a simple file and directory structure whenever possible, since it makes everything more portable and easier to read. If, as in your example, you find yourself doing a lot of ../css/styles.css then you may want to reconsider how things are structured.
Mix of 2 and 3. Use paths relative to a set variable.

Resources