Skip to content

Commit 6052251

Browse files
niiksergiou87
andcommitted
Test that stdin gets forwarded correctly
Co-Authored-By: Sergio Padrino <[email protected]>
1 parent f99853f commit 6052251

File tree

3 files changed

+90
-22
lines changed

3 files changed

+90
-22
lines changed

index.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
export function getDesktopAskpassTrampolinePath(): string
22
export function getDesktopAskpassTrampolineFilename(): string
33

4+
export function getDesktopCredentialHelperTrampolinePath(): string
5+
export function getDesktopCredentialHelperTrampolineFilename(): string
6+
47
export function getSSHWrapperPath(): string
58
export function getSSHWrapperFilename(): string

index.js

+17
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ function getDesktopAskpassTrampolineFilename() {
1515
: 'desktop-askpass-trampoline'
1616
}
1717

18+
function getDesktopCredentialHelperTrampolinePath() {
19+
return Path.join(
20+
__dirname,
21+
'build',
22+
'Release',
23+
getDesktopCredentialHelperTrampolineFilename()
24+
)
25+
}
26+
27+
function getDesktopCredentialHelperTrampolineFilename() {
28+
return process.platform === 'win32'
29+
? 'desktop-credential-helper-trampoline.exe'
30+
: 'desktop-credential-helper-trampoline'
31+
}
32+
1833
function getSSHWrapperPath() {
1934
return Path.join(__dirname, 'build', 'Release', getSSHWrapperFilename())
2035
}
@@ -26,6 +41,8 @@ function getSSHWrapperFilename() {
2641
module.exports = {
2742
getDesktopAskpassTrampolinePath,
2843
getDesktopAskpassTrampolineFilename,
44+
getDesktopCredentialHelperTrampolinePath,
45+
getDesktopCredentialHelperTrampolineFilename,
2946
getSSHWrapperPath,
3047
getSSHWrapperFilename,
3148
}

test/desktop-trampoline.test.js

+70-22
Original file line numberDiff line numberDiff line change
@@ -2,63 +2,111 @@ const { stat, access } = require('fs').promises
22
const { constants } = require('fs')
33
const { execFile } = require('child_process')
44
const { promisify } = require('util')
5-
const { getDesktopAskpassTrampolinePath } = require('../index')
5+
const { getDesktopAskpassTrampolinePath, getDesktopCredentialHelperTrampolinePath } = require('../index')
66
const split2 = require('split2')
77
const { createServer } = require('net')
88

9-
const trampolinePath = getDesktopAskpassTrampolinePath()
9+
const askPassTrampolinePath = getDesktopAskpassTrampolinePath()
10+
const helperTrampolinePath = getDesktopCredentialHelperTrampolinePath()
1011
const run = promisify(execFile)
1112

1213
describe('desktop-trampoline', () => {
1314
it('exists and is a regular file', async () =>
14-
expect((await stat(trampolinePath)).isFile()).toBe(true))
15+
expect((await stat(askPassTrampolinePath)).isFile()).toBe(true))
1516

1617
it('can be executed by current process', () =>
17-
access(trampolinePath, constants.X_OK))
18+
access(askPassTrampolinePath, constants.X_OK))
1819

1920
it('fails when required environment variables are missing', () =>
20-
expect(run(trampolinePath, ['Username'])).rejects.toThrow())
21+
expect(run(askPassTrampolinePath, ['Username'])).rejects.toThrow())
2122

22-
it('forwards arguments and valid environment variables correctly', async () => {
23+
const captureSession = () => {
2324
const output = []
25+
let resolveOutput = null
26+
27+
const outputPromise = new Promise(resolve => {
28+
resolveOutput = resolve
29+
})
30+
2431
const server = createServer(socket => {
32+
let timeoutId = null
2533
socket.pipe(split2(/\0/)).on('data', data => {
2634
output.push(data.toString('utf8'))
27-
})
2835

29-
// Don't send anything and just close the socket after the trampoline is
30-
// done forwarding data.
31-
socket.end()
36+
// Hack: consider the session finished after 100ms of inactivity.
37+
// In a real-world scenario, you'd have to parse the data to know when
38+
// the session is finished.
39+
if (timeoutId !== null) {
40+
clearTimeout(timeoutId)
41+
timeoutId = null
42+
}
43+
timeoutId = setTimeout(() => {
44+
resolveOutput(output)
45+
socket.end()
46+
server.close()
47+
}, 100)
48+
})
3249
})
33-
server.unref()
34-
35-
const startTrampolineServer = async () => {
36-
return new Promise((resolve, reject) => {
37-
server.on('error', e => reject(e))
38-
server.listen(0, '127.0.0.1', () => {
39-
resolve(server.address().port)
40-
})
50+
51+
const serverPortPromise = new Promise((resolve, reject) => {
52+
server.on('error', e => reject(e))
53+
server.listen(0, '127.0.0.1', () => {
54+
resolve(server.address().port)
4155
})
42-
}
56+
})
57+
58+
return [serverPortPromise, outputPromise]
59+
}
60+
61+
it('forwards arguments and valid environment variables correctly', async () => {
62+
63+
const [portPromise, outputPromise] = captureSession()
64+
const port = await portPromise
4365

44-
const port = await startTrampolineServer()
4566
const env = {
4667
DESKTOP_TRAMPOLINE_TOKEN: '123456',
4768
DESKTOP_PORT: port,
4869
INVALID_VARIABLE: 'foo bar',
4970
}
5071
const opts = { env }
5172

52-
await run(trampolinePath, ['baz'], opts)
73+
await run(askPassTrampolinePath, ['baz'], opts)
5374

75+
const output = await outputPromise
5476
const outputArguments = output.slice(1, 2)
5577
expect(outputArguments).toStrictEqual(['baz'])
5678
// output[2] is the number of env variables
5779
const envc = parseInt(output[2])
5880
const outputEnv = output.slice(3, 3 + envc)
5981
expect(outputEnv).toHaveLength(1)
6082
expect(outputEnv).toContain('DESKTOP_TRAMPOLINE_TOKEN=123456')
83+
})
84+
85+
it('forwards stdin when running in credential-helper mode', async () => {
86+
87+
const [portPromise, outputPromise] = captureSession()
88+
const port = await portPromise
89+
90+
const cp = run(helperTrampolinePath, ['get'], { env: { DESKTOP_PORT: port } })
91+
cp.child.stdin.end('oh hai\n')
92+
93+
await cp
94+
95+
const output = await outputPromise
96+
expect(output.at(-1)).toBe('oh hai\n')
97+
})
98+
99+
it('doesn\'t forward stdin when running in askpass mode', async () => {
100+
101+
const [portPromise, outputPromise] = captureSession()
102+
const port = await portPromise
103+
104+
const cp = run(askPassTrampolinePath, ['get'], { env: { DESKTOP_PORT: port } })
105+
cp.child.stdin.end('oh hai\n')
106+
107+
await cp
61108

62-
server.close()
109+
const output = await outputPromise
110+
expect(output.at(-1)).toBe('')
63111
})
64112
})

0 commit comments

Comments
 (0)