How can I script the op signin via a node application?
I'm working on some node scripts/apps that will simplify my life on multiple platforms when using the op CLI and have a question on stack overflow which I'd love for someone to take a look at and provide some feedback if possible: https://stackoverflow.com/q/56438183/1165441
1Password Version: 0.5.6
Extension Version: Not Provided
OS Version: Mac OS
Sync Type: Not Provided
Comments
-
Hey @eddiehedges
We don't provide support on Stack Overflow; this forum is for 1Password support.
Feel free to ask a question here for support, but note we cannot provide debugging assistance on your node app. We can answer questions on and around the CLI, such as how it receives and outputs data.
0 -
I'm simply using node to invoke an
op
command and am running into an error when the password prompt appears. Since the CLI is not open source and I haven't attempted to decompile/figure out how to access the source is there some information that you'd be able to provide to me so that I may continue in my efforts of scripting the signin process? Are there alternatives that take the master password as an argument or is this a feature that could be added? Or even more generally how does that prompt receive and output data?0 -
Here is the full CLI command documentation: https://support.1password.com/command-line/
You can pass a signin domain, email, and secret key like so
op signin <signinaddress> <emailaddress> <secretkey>
.Putting a master password in a script or as an argument is something we strongly recommend against; it should only be in your head, never written down beyond on your recovery kit.
The signin password prompt is set up to read from
stdin
or from/dev/tty
.0 -
Any idea as to why it's crashing the child_process
spawn
call? I can't even get the script to acceptstdin
since it crashes before that.0 -
@eddiehedges I had some issues to launch the
op
cli in python as well. If I compare with what I did, try to spawn the command in a shell and pass the full environment.0 -
Thanks @mickael I'll give that a shot.
0 -
Let us know how it goes!
0 -
I am trying to do exactly the same thing. Trying to automate moving from lastpass to 1password with shared folders, etc. I am trying to invoke op from a node program and it doesn't work. I keep getting an error saying "[LOG] 2019/08/05 16:48:40 (ERROR) operation not supported on socket"
Is op actively blocking being spawned from a node process somehow? All other programs seem to be working with the approach I am using.
`
const { spawn } = require('child_process')
const {streamWrite, streamEnd, onExit} = require('@rauschma/stringio');const signInTo1Password = async (onePasswordCredentials) => { const subprocess = spawn(opPath, [ 'signin', '1password team url', onePasswordCredentials.username, onePasswordCredentials.secretKey, '--output=raw'], { stdio: ['pipe', process.stdout, process.stderr] }) writeToWritable(subprocess.stdin) await onExit(subprocess) } async function writeToWritable(writable) { await streamWrite(writable, 'my 1password secret password\n'); await streamEnd(writable); }
`
0 -
We do not actively block our program from being used in any way. Ideally you should be able to use it every way!
Generally, if you can reproduce this in a shell, I can help determine how the program is either being called incorrectly, or behaving incorrectly.
As a person who is not familiar with Node and spawning binaries, what exactly are you are trying to do? I'm guessing this is just a shell wrapper for
op
.From what I see here, you spawn a subprocess off the main Node process containing
op
and the siginin parameters. The standard out of that subprocess is then piped into the standard out and standard error of the containing process. Then you write your master password to the standard in. (I hope that is not saved in the same place as the rest of your credentials :wink: )Where exactly is it failing? What are the surrounding errors? Can you reproduce it in a shell?
Also, have you tried @mickael 's suggestion? This is to:
try to spawn the command in a shell and pass the full environment
0 -
I had to use node-pty to simulate a shell to get around the problem. node-pty simulates a shell for you.. the code looks like this
const os = require('os') const pty = require('node-pty') const TOKEN_REGEX = new RegExp('^(.{43})$', 'gm') // the token is always 43 chars const LOGIN_COMMAND = 'op signin https://myteam.1password.com myemail <my secret key> --output=raw' const PASSWORD = 'password' const SHELL = os.platform() === 'win32' ? 'cmd.exe' : 'bash' const ptyProcess = pty.spawn(SHELL, [], { name: 'xterm-color', cols: 80, rows: 30, cwd: process.env.HOME, env: process.env, }) let result = '' ptyProcess.on('data', function(data) { result += data.toString() if (result.endsWith('at myteam.1password.com: ')) { console.log('entering password') ptyProcess.write(`${PASSWORD}\r`) } const tokenMatches = TOKEN_REGEX.exec(result) if (tokenMatches) { const token = tokenMatches[1] console.log('got token!', token) ptyProcess.kill() } }) ptyProcess.write(`${LOGIN_COMMAND}\r`)
This token works when I run the above program as is. For some reason, the token is not usable in my electron application when I subsequently use it later. To get past this, I had to force the user to open a terminal do a op signin (i give them the command they can copy paste) and obtain a token. They then paste the token into the app to proceed.
(Edited by @graham_1P for code formatting)
0 -
We were running into the same problem in Node 13 and later (it does appear to work with version 12). Looks like it has something to do with the standard in and error setup which can be fixed by setting it to
inherit
when spawning the process in Node like this:const { spawn } = require('child_process'); const cmd = 'op'; const args = [ 'get', 'item', 'staging-payments-key' ]; const proc = spawn( cmd, // the command you want to run, in my case `op` args, // arguments you want to use with the above cmd `signin`, etc. { stdio: [ 'inherit', // stdin: changed from the default `pipe` 'pipe', // stdout 'inherit' // stderr: changed from the default `pipe` ] }); var result = ''; proc.stdout.on('data', function (data) { result += data.toString(); }); proc.on('close', function (code) { console.log(result); });
0 -
@daffl : @askriz is right that by default if you spawn a process in Node.js, Node.js creates new pipes/file descriptors for stdin,stdout and stderr for the new process. The new process won't be connected to the terminal. See https://nodejs.org/api/child_process.html#child_process_options_stdio for more information.
Having said that, I can understand why
op signin
would throw an error (as mentioned in the original post) but where stdin and stderr point to shouldn't matter for other commands. I will investigate this to make sure we aren't doing anything weird in that regard.Thank you both!
0