2021-04-15 21:53:45 -04:00
|
|
|
const t = require('tap')
|
2023-01-16 22:38:23 -05:00
|
|
|
const mockNpm = require('../../fixtures/mock-npm')
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const mockToken = async (t, { profile, getCredentialsByURI, readUserInfo, ...opts } = {}) => {
|
|
|
|
const mocks = {}
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
if (profile) {
|
|
|
|
mocks['npm-profile'] = profile
|
|
|
|
}
|
2021-03-11 17:54:23 -05:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
if (readUserInfo) {
|
|
|
|
mocks['{LIB}/utils/read-user-info.js'] = readUserInfo
|
2020-10-02 17:52:19 -04:00
|
|
|
}
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const mock = await mockNpm(t, {
|
|
|
|
...opts,
|
2023-06-08 05:24:49 -07:00
|
|
|
command: 'token',
|
2023-01-16 22:38:23 -05:00
|
|
|
mocks,
|
|
|
|
})
|
|
|
|
|
|
|
|
// XXX: replace with mock registry
|
|
|
|
if (getCredentialsByURI) {
|
|
|
|
mock.npm.config.getCredentialsByURI = getCredentialsByURI
|
2020-10-02 17:52:19 -04:00
|
|
|
}
|
|
|
|
|
2023-06-08 05:24:49 -07:00
|
|
|
return mock
|
2023-01-16 22:38:23 -05:00
|
|
|
}
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
t.test('completion', async t => {
|
2023-06-08 05:24:49 -07:00
|
|
|
const { token } = await mockToken(t)
|
2021-12-02 22:04:46 +00:00
|
|
|
|
2020-10-02 17:52:19 -04:00
|
|
|
const testComp = (argv, expect) => {
|
2023-06-08 05:24:49 -07:00
|
|
|
t.resolveMatch(token.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' '))
|
2020-10-02 17:52:19 -04:00
|
|
|
}
|
|
|
|
|
2021-03-01 11:38:43 -05:00
|
|
|
testComp(['npm', 'token'], ['list', 'revoke', 'create'])
|
2020-10-02 17:52:19 -04:00
|
|
|
testComp(['npm', 'token', 'list'], [])
|
|
|
|
testComp(['npm', 'token', 'revoke'], [])
|
|
|
|
testComp(['npm', 'token', 'create'], [])
|
|
|
|
|
2023-06-08 05:24:49 -07:00
|
|
|
t.rejects(token.completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), {
|
2021-11-18 20:58:02 +00:00
|
|
|
message: 'foobar not recognize',
|
|
|
|
})
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token foobar', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t)
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2021-11-18 20:58:02 +00:00
|
|
|
await t.rejects(token.exec(['foobar']), /foobar is not a recognized subcommand/)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token list', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const now = new Date().toISOString()
|
2021-11-18 20:58:02 +00:00
|
|
|
const tokens = [
|
|
|
|
{
|
|
|
|
key: 'abcd1234abcd1234',
|
|
|
|
token: 'efgh5678efgh5678',
|
|
|
|
cidr_whitelist: null,
|
|
|
|
readonly: false,
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'abcd1256',
|
|
|
|
token: 'hgfe8765',
|
|
|
|
cidr_whitelist: ['192.168.1.1/32'],
|
|
|
|
readonly: true,
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
},
|
|
|
|
]
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', otp: '123456' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: conf => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.same(conf.auth, { token: 'thisisnotarealtoken', otp: '123456' })
|
|
|
|
return tokens
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec([])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
const lines = joinedOutput().split(/\r?\n/)
|
|
|
|
t.match(lines[3], ' abcd123 ', 'includes the trimmed key')
|
|
|
|
t.match(lines[3], ' efgh56… ', 'includes the trimmed token')
|
|
|
|
t.match(lines[3], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp')
|
|
|
|
t.match(lines[3], ' no ', 'includes the "no" string for readonly state')
|
|
|
|
t.match(lines[5], ' abcd125 ', 'includes the trimmed key')
|
|
|
|
t.match(lines[5], ' hgfe87… ', 'includes the trimmed token')
|
|
|
|
t.match(lines[5], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp')
|
|
|
|
t.match(lines[5], ' yes ', 'includes the "no" string for readonly state')
|
|
|
|
t.match(lines[5], ` ${tokens[1].cidr_whitelist.join(',')} `, 'includes the cidr whitelist')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token list json output', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const now = new Date().toISOString()
|
2021-11-18 20:58:02 +00:00
|
|
|
const tokens = [
|
|
|
|
{
|
|
|
|
key: 'abcd1234abcd1234',
|
|
|
|
token: 'efgh5678efgh5678',
|
|
|
|
cidr_whitelist: null,
|
|
|
|
readonly: false,
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
},
|
|
|
|
]
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', json: true },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { username: 'foo', password: 'bar' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: conf => {
|
|
|
|
t.same(
|
|
|
|
conf.auth,
|
|
|
|
{ basic: { username: 'foo', password: 'bar' } },
|
|
|
|
'passes the correct auth'
|
|
|
|
)
|
2020-10-02 17:52:19 -04:00
|
|
|
return tokens
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
})
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['list'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
const parsed = JSON.parse(joinedOutput())
|
|
|
|
t.match(parsed, tokens, 'prints the json parsed tokens')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token list parseable output', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const now = new Date().toISOString()
|
2021-11-18 20:58:02 +00:00
|
|
|
const tokens = [
|
|
|
|
{
|
|
|
|
key: 'abcd1234abcd1234',
|
|
|
|
token: 'efgh5678efgh5678',
|
|
|
|
cidr_whitelist: null,
|
|
|
|
readonly: false,
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'efgh5678ijkl9101',
|
|
|
|
token: 'hgfe8765',
|
|
|
|
cidr_whitelist: ['192.168.1.1/32'],
|
|
|
|
readonly: true,
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
},
|
|
|
|
]
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', parseable: true },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { auth: Buffer.from('foo:bar').toString('base64') }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: conf => {
|
|
|
|
t.same(
|
|
|
|
conf.auth,
|
|
|
|
{ basic: { username: 'foo', password: 'bar' } },
|
|
|
|
'passes the correct auth'
|
|
|
|
)
|
2020-10-02 17:52:19 -04:00
|
|
|
return tokens
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['list'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
const lines = joinedOutput().split(/\r?\n/)
|
|
|
|
|
|
|
|
t.equal(
|
|
|
|
lines[0],
|
|
|
|
['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t'),
|
|
|
|
'prints header'
|
|
|
|
)
|
|
|
|
|
|
|
|
t.equal(
|
|
|
|
lines[1],
|
|
|
|
[tokens[0].key, tokens[0].token, tokens[0].created, tokens[0].readonly, ''].join('\t'),
|
|
|
|
'prints token info'
|
|
|
|
)
|
|
|
|
|
|
|
|
t.equal(
|
|
|
|
lines[2],
|
|
|
|
[
|
|
|
|
tokens[1].key,
|
|
|
|
tokens[1].token,
|
|
|
|
tokens[1].created,
|
|
|
|
tokens[1].readonly,
|
|
|
|
tokens[1].cidr_whitelist.join(','),
|
|
|
|
].join('\t'),
|
|
|
|
'prints token info'
|
|
|
|
)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return {}
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: conf => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.same(conf.auth, {}, 'passes the correct empty auth')
|
2021-11-18 20:58:02 +00:00
|
|
|
return Promise.resolve([{ key: 'abcd1234' }])
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
2021-11-18 20:58:02 +00:00
|
|
|
removeToken: key => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.equal(key, 'abcd1234', 'deletes the correct token')
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['rm', 'abcd'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
t.equal(joinedOutput(), 'Removed 1 token')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke multiple tokens', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: () => Promise.resolve([{ key: 'abcd1234' }, { key: 'efgh5678' }]),
|
|
|
|
removeToken: key => {
|
2020-10-02 17:52:19 -04:00
|
|
|
// this will run twice
|
|
|
|
t.ok(['abcd1234', 'efgh5678'].includes(key), 'deletes the correct token')
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['revoke', 'abcd', 'efgh'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
t.equal(joinedOutput(), 'Removed 2 tokens')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke json output', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', json: true },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: () => Promise.resolve([{ key: 'abcd1234' }]),
|
|
|
|
removeToken: key => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.equal(key, 'abcd1234', 'deletes the correct token')
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
})
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['delete', 'abcd'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
const parsed = JSON.parse(joinedOutput())
|
|
|
|
t.same(parsed, ['abcd1234'], 'logs the token as json')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke parseable output', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', parseable: true },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: () => Promise.resolve([{ key: 'abcd1234' }]),
|
|
|
|
removeToken: key => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.equal(key, 'abcd1234', 'deletes the correct token')
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['remove', 'abcd'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
t.equal(joinedOutput(), 'abcd1234', 'logs the token as a string')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke by token', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: () => Promise.resolve([{ key: 'abcd1234', token: 'efgh5678' }]),
|
|
|
|
removeToken: key => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.equal(key, 'efgh5678', 'passes through user input')
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['rm', 'efgh5678'])
|
2023-01-16 22:38:23 -05:00
|
|
|
t.equal(joinedOutput(), 'Removed 1 token')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke requires an id', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t)
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2021-11-18 20:58:02 +00:00
|
|
|
await t.rejects(token.exec(['rm']), /`<tokenKey>` argument is required/)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke ambiguous id errors', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: () => Promise.resolve([{ key: 'abcd1234' }, { key: 'abcd5678' }]),
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-18 20:58:02 +00:00
|
|
|
await t.rejects(token.exec(['rm', 'abcd']), /Token ID "abcd" was ambiguous/)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token revoke unknown id errors', async t => {
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
2021-11-18 20:58:02 +00:00
|
|
|
listTokens: () => Promise.resolve([{ key: 'abcd1234' }]),
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-18 20:58:02 +00:00
|
|
|
await t.rejects(token.exec(['rm', 'efgh']), /Unknown token id or value "efgh"./)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token create', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const now = new Date().toISOString()
|
|
|
|
const password = 'thisisnotreallyapassword'
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: {
|
|
|
|
registry: 'https://registry.npmjs.org',
|
|
|
|
cidr: ['10.0.0.0/8', '192.168.1.0/24'],
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
2023-01-16 22:38:23 -05:00
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
readUserInfo: {
|
2020-11-17 15:37:44 -05:00
|
|
|
password: () => Promise.resolve(password),
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
|
|
|
createToken: (pw, readonly, cidr) => {
|
|
|
|
t.equal(pw, password)
|
2023-01-16 22:38:23 -05:00
|
|
|
t.equal(readonly, false)
|
2020-10-02 17:52:19 -04:00
|
|
|
t.same(cidr, ['10.0.0.0/8', '192.168.1.0/24'], 'defaults to empty array')
|
|
|
|
return {
|
|
|
|
key: 'abcd1234',
|
|
|
|
token: 'efgh5678',
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
readonly: false,
|
2020-11-17 15:37:44 -05:00
|
|
|
cidr_whitelist: [],
|
2020-10-02 17:52:19 -04:00
|
|
|
}
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
})
|
2020-10-02 17:52:19 -04:00
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['create'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
const lines = joinedOutput().split(/\r?\n/)
|
|
|
|
t.match(lines[1], 'token')
|
|
|
|
t.match(lines[1], 'efgh5678', 'prints the whole token')
|
|
|
|
t.match(lines[3], 'created')
|
|
|
|
t.match(lines[3], now, 'prints the correct timestamp')
|
|
|
|
t.match(lines[5], 'readonly')
|
|
|
|
t.match(lines[5], 'false', 'prints the readonly flag')
|
|
|
|
t.match(lines[7], 'cidr_whitelist')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token create json output', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const now = new Date().toISOString()
|
|
|
|
const password = 'thisisnotreallyapassword'
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', json: true },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
readUserInfo: {
|
2020-11-17 15:37:44 -05:00
|
|
|
password: () => Promise.resolve(password),
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
|
|
|
createToken: (pw, readonly, cidr) => {
|
|
|
|
t.equal(pw, password)
|
2023-01-16 22:38:23 -05:00
|
|
|
t.equal(readonly, false)
|
2020-10-02 17:52:19 -04:00
|
|
|
t.same(cidr, [], 'defaults to empty array')
|
|
|
|
return {
|
|
|
|
key: 'abcd1234',
|
|
|
|
token: 'efgh5678',
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
readonly: false,
|
2020-11-17 15:37:44 -05:00
|
|
|
cidr_whitelist: [],
|
2020-10-02 17:52:19 -04:00
|
|
|
}
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
2021-11-18 20:58:02 +00:00
|
|
|
output: spec => {
|
2020-10-02 17:52:19 -04:00
|
|
|
t.type(spec, 'string', 'outputs a string')
|
|
|
|
const parsed = JSON.parse(spec)
|
2021-11-18 20:58:02 +00:00
|
|
|
t.same(
|
|
|
|
parsed,
|
|
|
|
{ token: 'efgh5678', created: now, readonly: false, cidr_whitelist: [] },
|
|
|
|
'outputs the correct object'
|
|
|
|
)
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['create'])
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token create parseable output', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const now = new Date().toISOString()
|
|
|
|
const password = 'thisisnotreallyapassword'
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token, joinedOutput } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', parseable: true },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
readUserInfo: {
|
2020-11-17 15:37:44 -05:00
|
|
|
password: () => Promise.resolve(password),
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
profile: {
|
|
|
|
createToken: (pw, readonly, cidr) => {
|
|
|
|
t.equal(pw, password)
|
2023-01-16 22:38:23 -05:00
|
|
|
t.equal(readonly, false)
|
2020-10-02 17:52:19 -04:00
|
|
|
t.same(cidr, [], 'defaults to empty array')
|
|
|
|
return {
|
|
|
|
key: 'abcd1234',
|
|
|
|
token: 'efgh5678',
|
|
|
|
created: now,
|
|
|
|
updated: now,
|
|
|
|
readonly: false,
|
2020-11-17 15:37:44 -05:00
|
|
|
cidr_whitelist: [],
|
2020-10-02 17:52:19 -04:00
|
|
|
}
|
2020-11-17 15:37:44 -05:00
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await token.exec(['create'])
|
2023-01-16 22:38:23 -05:00
|
|
|
|
|
|
|
const spec = joinedOutput().split(/\r?\n/)
|
|
|
|
|
|
|
|
t.match(spec[0], 'token\tefgh5678', 'prints the token')
|
|
|
|
t.match(spec[1], `created\t${now}`, 'prints the created timestamp')
|
|
|
|
t.match(spec[2], 'readonly\tfalse', 'prints the readonly flag')
|
|
|
|
t.match(spec[3], 'cidr_whitelist\t', 'prints the cidr whitelist')
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token create ipv6 cidr', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const password = 'thisisnotreallyapassword'
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', cidr: '::1/128' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
readUserInfo: {
|
2020-11-17 15:37:44 -05:00
|
|
|
password: () => Promise.resolve(password),
|
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await t.rejects(
|
|
|
|
token.exec(['create']),
|
2021-11-18 20:58:02 +00:00
|
|
|
{
|
|
|
|
code: 'EINVALIDCIDR',
|
|
|
|
message: /CIDR whitelist can only contain IPv4 addresses, ::1\/128 is IPv6/,
|
|
|
|
},
|
2021-11-04 20:42:47 +00:00
|
|
|
'returns correct error'
|
|
|
|
)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
t.test('token create invalid cidr', async t => {
|
2020-10-02 17:52:19 -04:00
|
|
|
const password = 'thisisnotreallyapassword'
|
|
|
|
|
2023-01-16 22:38:23 -05:00
|
|
|
const { token } = await mockToken(t, {
|
|
|
|
config: { registry: 'https://registry.npmjs.org', cidr: 'apple/cider' },
|
|
|
|
getCredentialsByURI: uri => {
|
|
|
|
t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
|
|
|
|
return { token: 'thisisnotarealtoken' }
|
2020-10-02 17:52:19 -04:00
|
|
|
},
|
|
|
|
readUserInfo: {
|
2020-11-17 15:37:44 -05:00
|
|
|
password: () => Promise.resolve(password),
|
|
|
|
},
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|
|
|
|
|
2021-11-04 20:42:47 +00:00
|
|
|
await t.rejects(
|
|
|
|
token.exec(['create']),
|
|
|
|
{ code: 'EINVALIDCIDR', message: /CIDR whitelist contains invalid CIDR entry: apple\/cider/ },
|
|
|
|
'returns correct error'
|
|
|
|
)
|
2020-10-02 17:52:19 -04:00
|
|
|
})
|