node-keytar icon indicating copy to clipboard operation
node-keytar copied to clipboard

unable to transpile keytar module with babel

Open frankolson opened this issue 6 years ago • 10 comments

I have an Electron + create-react-app application where I am attempting to store user passwords in the local keychain. However, when I run the savePass function from the following code:

import keytar from 'keytar';

...

export const savePass = (savedKeyPairId, pass) => {
  return keytar.setPassword('Account', 'Service', pass);
}

I get the following error message:

Unhandled Rejection (TypeError): keytar.setPassword is not a function

Has anybody else run into this issue and/or know where I can start the debugging process?

frankolson avatar Jan 19 '18 06:01 frankolson

@frankolson I think your import statement is off.

This is how we do the import in GitHub Desktop (it's TypeScript, but the rest should map to your code):

import * as keytar from 'keytar'

function setItem(key: string, login: string, value: string) {
  return keytar.setPassword(key, login, value)
}

shiftkey avatar Jan 19 '18 15:01 shiftkey

@shiftkey, after looking at the source code, your suggestion definitely makes sense, thank you. Unfortunately, I am still getting the same error. I even logged the value of keytar to see what it was returning:

screen shot 2018-01-19 at 7 54 58 am

That error actually points to line 38 in lib/keytar.js which is the return statement of the function being exported as setPassword inside the keytar package.

frankolson avatar Jan 19 '18 16:01 frankolson

Hi:

I'm encountering the exact same issue, and I'm trying to load keytar inside the browser window, which I think might be a problem because it is an unprivileged context, compared to the script which creates the window. Correct me if this is a wrong assumption in Electron. In any case, keytar does not load in the electron-start script I have. Did you figure out how to solve this?

Thanks,

lduros avatar Mar 19 '18 18:03 lduros

I'm encountering this problem as well but for findPassword. Looking at the source, it's as if the require('../build/Release/keytar.node') statement is failing within lib\keytar.js.

I've moved all my code interacting with keytar to my main electron thread and call it via IPC from the renderer thread.

  getPassword = (service) => {
    console.log("keytar", keytar);
    return keytar.findPassword(service);
  }

Output:

keytar { getPassword: [Function: getPassword],
  setPassword: [Function: setPassword],
  deletePassword: [Function: deletePassword],
  findPassword: [Function: findPassword],
  findCredentials: [Function: findCredentials] }
TypeError: keytar.findPassword is not a function
    at callback (webpack:///./node_modules/keytar/lib/keytar.js?:51:47)
    at eval (webpack:///./node_modules/keytar/lib/keytar.js?:12:7)
    at Promise (<anonymous>)
    at callbackPromise (webpack:///./node_modules/keytar/lib/keytar.js?:11:12)
    at Object.findPassword (webpack:///./node_modules/keytar/lib/keytar.js?:51:12)
    at exports.default.getPassword.service [as getPassword] (webpack:///./src/electron/main/store.js?:41:31)
    at EventEmitter.relayServerPassword (webpack:///./src/electron/main/ipc.js?:118:16)
    at emitTwo (events.js:125:13)
    at EventEmitter.emit (events.js:213:7)
    at WebContents.<anonymous>

The keytar in scope is not the one causing the error, I believe it's the internal import in lib/keytar.js.

keytar: 4.2.1 (I've tested 4.2.0, 4.1.0 and 4.0.4 also, same issue)
nodejs: 9.8.0
electron: 1.8.4
building for x64

gknapp avatar Apr 12 '18 16:04 gknapp

I've downgraded to 3.0.2 and switched from import ... from to require() syntax (possibly futile as I'm transpiling with babel), still encountering keytar.findPassword is not a function

keytar-stacktrace

~~Would this issue have anything to do with the target version for prebuild of node 9.x being 9.4.0? I'm running 9.8.0.~~

Update: I downgraded my nodejs version to 9.4.0, then 8.8.1, the issue remains.

gknapp avatar Apr 30 '18 09:04 gknapp

So after much fiddling, I had to remove my main thread code from my webpack configuration so it wasn't transpiled by babel. When I left the source untouched and included it in my electron app (1.8.6, which uses node 8.2.1) keytar worked fine.

I'm not sure what babel is doing but you can't appear to consume keytar if you're transpiling code with it.

gknapp avatar May 02 '18 08:05 gknapp

@gknapp thanks for the extra details. If you've got an isolated repro of the issue to share that'd be great, but I'd also check that your webpack configuration is pulling in your native node modules. Here's an example of the loader we use in another Electron + webpack project that you might be missing:

https://github.com/desktop/desktop/blob/d338a73a3acbfbb5250d45863e19027fb73572b5/app/webpack.common.ts#L45-L51

shiftkey avatar Jan 21 '19 17:01 shiftkey

I made this change a while back. I'll see what I can dig up over the next 7-10 days, it's not my active project at present but it'd be good to have the whole code base transpiled so I can use consistent ES6 import / exports etc.

gknapp avatar Jan 21 '19 22:01 gknapp

any movement on this? I'm running into the same problem when using Babel

DnOberon avatar Aug 07 '20 02:08 DnOberon

I have the same problem. using Parcel, Rollup same error message. keytar.findCredentials is not a function changed the import statement from import { findCredentials } from "keytar"; TO import * as keytar from 'keytar' OR const keytar = require('keytar') didn't help.

saostad avatar Mar 02 '21 15:03 saostad