11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci// Test that mkdir with recursive option returns appropriate error 41cb0ef41Sopenharmony_ci// when executed on folder it does not have permission to access. 51cb0ef41Sopenharmony_ci// Ref: https://github.com/nodejs/node/issues/31481 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst common = require('../common'); 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciif (!common.isWindows && process.getuid() === 0) 101cb0ef41Sopenharmony_ci common.skip('as this test should not be run as `root`'); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciif (common.isIBMi) 131cb0ef41Sopenharmony_ci common.skip('IBMi has a different access permission mechanism'); 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciconst tmpdir = require('../common/tmpdir'); 161cb0ef41Sopenharmony_citmpdir.refresh(); 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciconst assert = require('assert'); 191cb0ef41Sopenharmony_ciconst { execSync } = require('child_process'); 201cb0ef41Sopenharmony_ciconst fs = require('fs'); 211cb0ef41Sopenharmony_ciconst path = require('path'); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_cilet n = 0; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_cifunction makeDirectoryReadOnly(dir) { 261cb0ef41Sopenharmony_ci let accessErrorCode = 'EACCES'; 271cb0ef41Sopenharmony_ci if (common.isWindows) { 281cb0ef41Sopenharmony_ci accessErrorCode = 'EPERM'; 291cb0ef41Sopenharmony_ci execSync(`icacls ${dir} /deny "everyone:(OI)(CI)(DE,DC,AD,WD)"`); 301cb0ef41Sopenharmony_ci } else { 311cb0ef41Sopenharmony_ci fs.chmodSync(dir, '444'); 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci return accessErrorCode; 341cb0ef41Sopenharmony_ci} 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_cifunction makeDirectoryWritable(dir) { 371cb0ef41Sopenharmony_ci if (common.isWindows) { 381cb0ef41Sopenharmony_ci execSync(`icacls ${dir} /remove:d "everyone"`); 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci} 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci// Synchronous API should return an EACCESS error with path populated. 431cb0ef41Sopenharmony_ci{ 441cb0ef41Sopenharmony_ci const dir = path.join(tmpdir.path, `mkdirp_${n++}`); 451cb0ef41Sopenharmony_ci fs.mkdirSync(dir); 461cb0ef41Sopenharmony_ci const codeExpected = makeDirectoryReadOnly(dir); 471cb0ef41Sopenharmony_ci let err = null; 481cb0ef41Sopenharmony_ci try { 491cb0ef41Sopenharmony_ci fs.mkdirSync(path.join(dir, '/foo'), { recursive: true }); 501cb0ef41Sopenharmony_ci } catch (_err) { 511cb0ef41Sopenharmony_ci err = _err; 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci makeDirectoryWritable(dir); 541cb0ef41Sopenharmony_ci assert(err); 551cb0ef41Sopenharmony_ci assert.strictEqual(err.code, codeExpected); 561cb0ef41Sopenharmony_ci assert(err.path); 571cb0ef41Sopenharmony_ci} 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci// Asynchronous API should return an EACCESS error with path populated. 601cb0ef41Sopenharmony_ci{ 611cb0ef41Sopenharmony_ci const dir = path.join(tmpdir.path, `mkdirp_${n++}`); 621cb0ef41Sopenharmony_ci fs.mkdirSync(dir); 631cb0ef41Sopenharmony_ci const codeExpected = makeDirectoryReadOnly(dir); 641cb0ef41Sopenharmony_ci fs.mkdir(path.join(dir, '/bar'), { recursive: true }, (err) => { 651cb0ef41Sopenharmony_ci makeDirectoryWritable(dir); 661cb0ef41Sopenharmony_ci assert(err); 671cb0ef41Sopenharmony_ci assert.strictEqual(err.code, codeExpected); 681cb0ef41Sopenharmony_ci assert(err.path); 691cb0ef41Sopenharmony_ci }); 701cb0ef41Sopenharmony_ci} 71