Files
tabby/tabby-ssh/test/authMethodSelection.test.ts
T

108 lines
3.2 KiB
TypeScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { selectNextAuthMethod, updateAuthPlanAfterFailure } from '../src/session/authMethodSelection.ts'
interface Method {
type: 'keyboard-interactive'|'password'|'publickey'
}
const authType = (method: Method): string => method.type
const createPartialSuccessFallback = (type: string): Method|null => {
if (type === 'keyboard-interactive') {
return { type }
}
return null
}
test('continues with keyboard-interactive after partial public-key success', () => {
let remainingMethods: Method[] = [{ type: 'publickey' }]
let allowedMethods = ['publickey']
const publicKey = selectNextAuthMethod(remainingMethods, allowedMethods, authType)
assert.equal(publicKey?.type, 'publickey')
remainingMethods = remainingMethods.filter(method => method !== publicKey)
const plan = updateAuthPlanAfterFailure(
remainingMethods,
{
partialSuccess: true,
remainingMethods: ['keyboard-interactive'],
},
authType,
createPartialSuccessFallback,
)
allowedMethods = plan.allowedMethods
assert.equal(selectNextAuthMethod(plan.remainingMethods, allowedMethods, authType)?.type, 'keyboard-interactive')
})
test('does not add keyboard-interactive after a full public-key rejection', () => {
const plan = updateAuthPlanAfterFailure(
[],
{
partialSuccess: false,
remainingMethods: ['keyboard-interactive'],
},
authType,
createPartialSuccessFallback,
)
assert.equal(selectNextAuthMethod(plan.remainingMethods, plan.allowedMethods, authType), undefined)
})
test('selects public-key for a public-key-only server', () => {
const method = selectNextAuthMethod<Method>(
[{ type: 'publickey' }, { type: 'keyboard-interactive' }],
['publickey'],
authType,
)
assert.equal(method?.type, 'publickey')
})
test('selects keyboard-interactive when it is the only advertised method', () => {
const method = selectNextAuthMethod<Method>(
[{ type: 'publickey' }, { type: 'keyboard-interactive' }],
['keyboard-interactive'],
authType,
)
assert.equal(method?.type, 'keyboard-interactive')
})
test('selects only methods advertised by the server', () => {
const method = selectNextAuthMethod<Method>(
[{ type: 'password' }, { type: 'publickey' }, { type: 'keyboard-interactive' }],
['keyboard-interactive'],
authType,
)
assert.equal(method?.type, 'keyboard-interactive')
})
test('stops when it runs out of methods to try', () => {
const plan = updateAuthPlanAfterFailure(
[] satisfies Method[],
{
partialSuccess: false,
remainingMethods: [],
},
authType,
createPartialSuccessFallback,
)
assert.deepEqual(plan.allowedMethods, [])
assert.equal(selectNextAuthMethod(plan.remainingMethods, plan.allowedMethods, authType), undefined)
})
test('tries everything when the server advertises no methods at all', () => {
const method = selectNextAuthMethod<Method>(
[{ type: 'publickey' }, { type: 'password' }],
[],
authType,
)
assert.equal(method?.type, 'publickey')
})