Linux directory permissions issue (NPM's node_modules directory) - linux

I'm trying to figure out how to get the permissions to work for me with my node_modules directory. Here's the problem...
user1 goes to a folder with a package.json and runs npm install resulting in a node_modules directory with the owner and group user1.
user2 then goes to that folder (it's a shared folder) and tries running something like npm install --save some_dep, but they don't have permissions on this directory so it fails.
Okay, that's fine.. so I chown -R the node_modules to be a shared group which both users are in.
Now user2 can run his command successfully resulting in a folder node_modules/some_dep. But now user1 doesn't have access to this folder.
So I try using a setgid permission on the node_modules directory. Something like chmod -R g+s node_modules. The result is exactly the same as before - when a user runs a NPM command the resulting directory gets the wrong group and permissions.
So I tried using ACLs, but the result is again the same.. the directories resulting from a user running an NPM command will not respect the permissions of the host folder.
Maybe this has something to do with how NPM dependencies are built. Maybe they are built elsewhere and then moved?
Is there any way to set permissions that are effective for that directory and all future subdirectories in such a way that I can make this work?
I could just run everything as root all the time... but this is clearly not ideal.

This appears to be due to a design flaw in npm. When creating the node_modules folder, npm (for reasons no one can explain) executes chown on the folder explicitly. Rather than relying on the OS to properly set permissions, npm mucks with problems, messes up your permissions, and makes it pretty much impossible to use it in a shared environment without periodic manual runs of chmod/chown.
This is likely the source of the endless trail of permissions-related issues people have trying to use npm.
Developers promise (for the nth time) this problem is fixed in later versions: https://github.com/npm/npm/blob/db9cde008ce855bdac801bb6649cbfb5bb7911ac/changelogs/CHANGELOG-2.md#v2120-2015-06-18

Related

What is the proper way of using npm in root environment?

I'm currently setting up a Parse Server with AWS EC2 instance, where I've been using Nginx and Elastic IP to manage SSL certificates.
Through different guides I've reached the solution of put the node app at /var/www/parse-server, but they say I should do 'npm init' in this directory, which is obviously owned by root (and fails because of permissions, of course).
My question is about the proper way of manipulate the app files in this root path, specially because 'sudo npm init' has conflicts with packages when the project keep moving on.
Should I use 'sudo su' and proceed with the install? I tried to do that, but npm init isn't recognized as a command. I haven't tried with --prefix yet, because I wanted to make sure before do that.
Should I use another directory to keep my application working? I've though that, but what about Nginx and all the related config?
Should I chown -R the folder to gain ownership of the /var/www/parse-server folder? If I do that, what about permissions later on?
I found two workarounds for this:
chown -R to change the directory owner to my own user. This works but i think is not the proper way.
Proxy reverse to the specific folder (i'm using nginx, so whoever is watching this thread should be fine with nginx docs)
Thanks to Davi Macedo for solution 1.

Laravel folder permission for not-yet made cache folders

I'm having an issue with directory permissions with Laravel when it comes to caching. Whenever it tries to upload a cache file to /var/www/laravel/storage/framework/cache/data/ it tells me that file_put_contents has no permissions.
To fix this I always do something like chmod -R 755 /var/www/laravel/storage/framework/cache/ but the problem here is that when it creates a new directory inside cache it does not inherit these chmod settings, thus giving me permission denied error again.
How can this be fixed permanently?
Edit:
Been thinking about letting it run as a cronjob regularly, but I'm not so sure that's a good way to deal with it.
You need to run chmod command with -R:
sudo chmod -R 755 storage
After installing Laravel, you may need to configure some permissions. Directories within the storage and the bootstrap/cache directories should be writable by your web server or Laravel will not run. If you are using the Homestead virtual machine, these permissions should already be set.
https://laravel.com/docs/5.5#installation

where should a module write files?

I wrote a CLI module, wikidata-cli, that for a certain command (wd props) caches results as files in the module directory: node_modules/wikidata-cli/props/some-file. It works in my local setup where node and npm were installed in my home folder (using nvm), but other people having installed node/npm from their package manager, probably with sudo rights, encounter issues: once installed, the module loses the permission to modify the module directory and they get errors of the kind EACCES: permission denied, open '/usr/lib/node_modules/wikidata-cli/props/de.json'
I tried changing the access permission during the postinstall script - "postinstall": "mkdir -p props && chown -R 666 props" - but had to revert it was blocking any installation with a operation forbidden error.
Any clue were this kind of file is expected to be written in a cross-platform compatible way?
If you're looking for the code to be able to write files no matter which user runs it, then there's really only one answer: The only folder that the current user a) is guaranteed to be able to write to, and b) won't encounter conflicts between different users accessing the same paths, is the user's own home directory.
You could use something like this to derive a path that the current user can definitely access:
var homePath = process.env.HOME || process.env.USERPROFILE; // POSIX || Win32
var moduleDataPath = path.join(homePath, ".wikidata-cli");
if (!fs.existsSync(moduleDataPath))
fs.mkdirSync(moduleDataPath);

Workspace Settings permission denied

I'm running Ubuntu 12.04LTS.
Have unpacked Visual Studio Code in a folder owned by my user id. All vscode files are owned by my user id (user and group).
Have Node.js, npm, typescript installed via apt-get (and npm).
Visual Studio code runs fine, however File->Preferences->Workspace Settings gives this error:
Unable to create 'vscode/settings.json' (Error: EACCES: permission denied, mkdir '/.vscode').
Any ideas on how to resolve this? Where is it trying to do the mkdir?
Thanks,
Bob Wirka
UPDATE: Sudo'd mkdir "/.vscode" (literally at the root level), and chown'd it recursively to my user and group. Voila! Now I can edit the settings.
So, is there a way to tell Visual Studio Code that it shouldn't be trying to use the root folder?
Mentioned in the update by the OP but thought I'll mention it explicitly. You need to change the permissions for the folder. The following command will change the owner of the directory so that you can open it without needing root privileges.
$ sudo chown <user-name> -R <directory-name>
I had same issue on my osx. I was able to solve this issue by change the permission to read and write in project folder.
Simply type
sudo chmod 777 -R <your_app_name_directory>.
This will give all permissions to all users, groups and others for read, write, execute.
-R gives recursively permissions to all nested files folders inside your directory.
If -R is not given then it gives permissions to current directory only, not to other directories inside.
Change the permissions to your folder
sudo chmod ugo+rwx your_folder

Bash scripting and user home from root account (Linux)

I'm writing an install script in bash for an application on Linux.
This script copies some files into /usr/bin and /usr/share, so it needs to be executed by a root user, furthermore it makes an hidden directory in the $HOME dir for configuration files.
Here is the problem: if a normal user wants to install the program, he needs to be root. But if he is root, the $HOME directory will be /root/ instead of /home/username.
...and, further, if UserA installs the software, but UserB runs it, UserB won't have the hidden directory under /home/UserB. Also, the hidden directory under /home/UserA will be owned by root, not userA.
So, you need to have the application create the hidden directory, not the installer.
Another possible option is not to install in the system directories; one possible alternative location is /usr/local. However, even that can require root privileges. Think about whether it can be installed in other places, and how it could locate its materials.
However, requiring root privileges to install is not the end of the world - a nuisance for some, but not completely out of order. But requiring everyone who uses to have root privileges is way out of order - and if everyone who uses it needs to run the installer, that is bad.
Final point (for now): if you use sudo, it does not change the value of $HOME, even as you acquire root privileges. However, requiring everyone who uses your application to have sudo privileges is not a good thing either.
Must you use $HOME? Maybe you could prompt for the username and install to ~$username instead?

Resources