1const t = require('tap') 2const fs = require('fs/promises') 3const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') 4const MockRegistry = require('@npmcli/mock-registry') 5const { join } = require('path') 6 7t.test('token logout - user config', async t => { 8 const { npm, home, logs } = await loadMockNpm(t, { 9 homeDir: { 10 '.npmrc': [ 11 '//registry.npmjs.org/:_authToken=@foo/', 12 'other-config=true', 13 ].join('\n'), 14 }, 15 }) 16 17 const mockRegistry = new MockRegistry({ tap: t, registry: 'https://registry.npmjs.org/' }) 18 mockRegistry.logout('@foo/') 19 await npm.exec('logout', []) 20 t.equal( 21 logs.verbose.find(l => l[0] === 'logout')[1], 22 'clearing token for https://registry.npmjs.org/', 23 'should log message with correct registry' 24 ) 25 const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') 26 t.equal(userRc.trim(), 'other-config=true') 27}) 28 29t.test('token scoped logout - user config', async t => { 30 const { npm, home, logs } = await loadMockNpm(t, { 31 config: { 32 scope: '@myscope', 33 }, 34 homeDir: { 35 '.npmrc': [ 36 '//diff-registry.npmjs.com/:_authToken=@bar/', 37 '//registry.npmjs.org/:_authToken=@foo/', 38 '@myscope:registry=https://diff-registry.npmjs.com/', 39 40 ].join('\n'), 41 }, 42 }) 43 44 const mockRegistry = new MockRegistry({ tap: t, registry: 'https://diff-registry.npmjs.com/' }) 45 mockRegistry.logout('@bar/') 46 await npm.exec('logout', []) 47 t.equal( 48 logs.verbose.find(l => l[0] === 'logout')[1], 49 'clearing token for https://diff-registry.npmjs.com/', 50 'should log message with correct registry' 51 ) 52 53 const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') 54 t.equal(userRc.trim(), '//registry.npmjs.org/:_authToken=@foo/') 55}) 56 57t.test('user/pass logout - user config', async t => { 58 const { npm, home, logs } = await loadMockNpm(t, { 59 homeDir: { 60 '.npmrc': [ 61 '//registry.npmjs.org/:username=foo', 62 '//registry.npmjs.org/:_password=bar', 63 'other-config=true', 64 ].join('\n'), 65 }, 66 }) 67 68 await npm.exec('logout', []) 69 t.equal( 70 logs.verbose.find(l => l[0] === 'logout')[1], 71 'clearing user credentials for https://registry.npmjs.org/', 72 'should log message with correct registry' 73 ) 74 75 const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') 76 t.equal(userRc.trim(), 'other-config=true') 77}) 78 79t.test('missing credentials', async t => { 80 const { npm } = await loadMockNpm(t) 81 82 await t.rejects( 83 npm.exec('logout', []), 84 { 85 code: 'ENEEDAUTH', 86 message: /not logged in to https:\/\/registry.npmjs.org\/, so can't log out!/, 87 }, 88 'should reject with expected error code' 89 ) 90}) 91 92t.test('ignore invalid scoped registry config', async t => { 93 const { npm, home, logs } = await loadMockNpm(t, { 94 config: { scope: '@myscope' }, 95 homeDir: { 96 '.npmrc': [ 97 '//registry.npmjs.org/:_authToken=@foo/', 98 'other-config=true', 99 100 ].join('\n'), 101 }, 102 }) 103 104 const mockRegistry = new MockRegistry({ tap: t, registry: 'https://registry.npmjs.org/' }) 105 mockRegistry.logout('@foo/') 106 await npm.exec('logout', []) 107 108 t.equal( 109 logs.verbose.find(l => l[0] === 'logout')[1], 110 'clearing token for https://registry.npmjs.org/', 111 'should log message with correct registry' 112 ) 113 const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') 114 t.equal(userRc.trim(), 'other-config=true') 115}) 116 117t.test('token logout - project config', async t => { 118 const { npm, home, logs, prefix } = await loadMockNpm(t, { 119 homeDir: { 120 '.npmrc': [ 121 '//registry.npmjs.org/:_authToken=@foo/', 122 'other-config=true', 123 ].join('\n'), 124 }, 125 prefixDir: { 126 '.npmrc': [ 127 '//registry.npmjs.org/:_authToken=@bar/', 128 'other-config=true', 129 ].join('\n'), 130 }, 131 }) 132 133 const mockRegistry = new MockRegistry({ tap: t, registry: 'https://registry.npmjs.org/' }) 134 mockRegistry.logout('@bar/') 135 await npm.exec('logout', []) 136 137 t.equal( 138 logs.verbose.find(l => l[0] === 'logout')[1], 139 'clearing token for https://registry.npmjs.org/', 140 'should log message with correct registry' 141 ) 142 const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') 143 t.equal(userRc.trim(), [ 144 '//registry.npmjs.org/:_authToken=@foo/', 145 'other-config=true', 146 ].join('\n'), 'leaves user config alone') 147 t.equal( 148 logs.verbose.find(l => l[0] === 'logout')[1], 149 'clearing token for https://registry.npmjs.org/', 150 'should log message with correct registry' 151 ) 152 const projectRc = await fs.readFile(join(prefix, '.npmrc'), 'utf-8') 153 t.equal(projectRc.trim(), 'other-config=true', 'removes project config') 154}) 155