SAFE Drive - OSX


A quick test last night with ls ~/SAFE didn’t work, so I’ll try with debug tonight (aussie time) and report back


Hi there, the above returns:

**safenetworkjs:web** SafenetworkApi() +0ms

**safenetworkjs:web** SafenetworkApi.initialise() +2ms

**safe-fuse:bin** try safeJsApi.safeApi.bootstrap()... +0ms

**safenetworkjs:cli** __dirname: /Users/Home/safenetwork-fuse/node_modules/safenetworkjs/src +0ms


**safenetworkjs:cli** Safe.bootstrap()

**safenetworkjs:cli** with appInfo: {"id":"safenetwork-fuse","name":"SAFE Network FUSE","vendor":"theWebalyst"} argv: {"_":[],"version":false,"help":false,"$0":"bin.js"} +0ms

**safenetworkjs:cli** getLibPath() returning: /Users/Home/safenetwork-fuse/node_modules/@maidsafe/safe-node-app/src/native +1ms

**safenetworkjs:cli** call Safe.initializeApp()... +0ms

**safenetworkjs:cli** call app.auth.genAuthUri()... +49ms

**safenetworkjs:cli** bootstrap.authorise() with appInfo: {"id":"safenetwork-fuse","name":"SAFE Network FUSE","vendor":"theWebalyst","customExecPath":["/usr/local/bin/node","/Users/Home/safenetwork-fuse/bin.js","--pid","59181","--uri"]}appContainers: {"_public":["Read","Insert","Update","Delete"],"_publicNames":["Read","Insert","Update","Delete"]} +16ms

**safenetworkjs:cli** wait a mo +39ms

**safenetworkjs:cli** ipcReceive(59181) +0ms

**safenetworkjs:cli** ipcReceive(59181) +0ms

Server path not specified, so defaulting to ipc.config.socketRoot + ipc.config.appspace + /tmp/app.59181

starting server on /tmp/app.59181 

starting TLS server false

starting server as Unix || Windows Socket

but the drive doesn’t seem to be mounted. I wonder whether it’s due to osxfuse volumes being “remote”


All that is good, and it is waiting to authorise with the Browser.

If you have Peruse running and logged in to your account when you run SAFE Drive, Peruse should prompt you to authorise access, and if you agree that is when the drive will try to mount.

Did you have Peruse running? You should try with Peruse 0.7 (production, not dev), although it should work with any recent browser AFAIK because it is only being used to auth with the network.

EDIT: thanks for the OXS Fuse link which might come in handy at some point. As I read it the ‘remote’ point is just saying that FUSE is - remote - from the kernel (ie in user space) which is the case for all FUSE systems. Anyway, the problem you are seeing is not to do with FUSE at all because we have not yet authorised with SAFE network, and so have not attempted to mount FUSE. Poor FUSE, being blamed before it even gets to join in! :frowning:


@happybeing maybe my previous post wasn’t clear, apologies.
SAFE network FUSE is already authorised:

running Peruse 0.7.0 (

here’s the list of mounted drives btw

MacBook-Pro-2:~ Home$ diskutil list
/dev/disk0 (internal):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                         251.0 GB   disk0
   1:                        EFI EFI                     314.6 MB   disk0s1
   2:                 Apple_APFS Container disk1         250.7 GB   disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.7 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            105.6 GB   disk1s1
   2:                APFS Volume Preboot                 23.2 MB    disk1s2
   3:                APFS Volume Recovery                519.0 MB   disk1s3
   4:                APFS Volume VM                      4.3 GB     disk1s4

/dev/disk2 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +1.2 GB     disk2
   1:                  Apple_HFS VMware Fusion           1.0 GB     disk2s1


Ah ok. I would try revoking that and then try again, listing the steps as you go and what happens. Just so we are on the same page.

It looks though as if there is a problem with the authorisation being returned to the app (SAFE Drive).

This might be due to a difference in how Mac handles command line args, because they play a part in that dance. I don’t know how to solve that but maybe @joshuef or another Mac user can make some suggestions, and myself and @bzee can poke around.

Not having a Mac makes this a bit tricky to investigate from here, assuming that is the source of the problem. Really we need some comment from a SAFE dev who knows this area, but I recall seeing in the code (of the web hosting manager - here it is) which I think was about an outstanding issue with auth requests on OSX, so that’s my first thought - to compare what we’re doing with what the WHM does because I think it might be different.

So thank you @Stout77, if you can just confirm as suggested above, I think you can pause on trying to get something working while we look into this, but if you have notes on how the README can be improved then that would help. I can guide you in how to edit it and submit a pull request, or if you don’t want to get into that by all means just tell me what you think needs changing.

Great work BTW. It helps a lot :slight_smile:

@joshuef @krishna is the issue for this code documented, and does it still apply? I’d like to track it if there’s an open issue for it:


Thank you @happybeing,

I confirm revoking and re-running same result.

I’ll stand by and try to put together amendments to the readme (might just publish them here…not sure I’m ready for a PR :wink:)


@happybeing openUri works on OSX now, yep!

I’ll dive in and give the safe drive a whirl and let you know where i get to :+1:


I can also confirm, I’m seeing the same behaviour on OSX, after an auth request in the browser, the log output chugs along, but no drive mounted.

How are you handling the ipc (receiving the safe-auth: url sent from the browser?). I’m happy to play around and see if I can get this accepting the ipc, just not sure where to look atm.


Thanks Josh. I’m still using v0.8.1 SAFE API so might that be the cause?

The auth IPC code is in safenetworkjs/src/bootstrap.js

I can’t claim any credit/blame :wink: it all belongs to @bzee. BTW the auth code works on Linux, and as of last night Windows.


Okay cool. I’ve been triggering the pid/uri command manually with some nonsense to test (/Users/josh/.nvm/versions/node/v8.11.2/bin/node /Users/josh/Projects/safe/forks/safenetwork-fuse/bin --pid 1323131 --uri safe-auth:asdasdad and i’m seeing the following error:

error:  { Error: connect ENOENT /tmp/app.1323131
    at Object._errnoException (util.js:992:11)
    at _exceptionWithHostPort (util.js:1014:20)
    at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1186:14)
  code: 'ENOENT',
  errno: 'ENOENT',
  syscall: 'connect',
  address: '/tmp/app.1323131' }
connection closed 1323131 /tmp/app.1323131 Infinity tries remaining of Infinity

which looks like the ipc server isn’t reachable :frowning:

I don’t have time to dig more just now but I’ll fire in again the morning :+1:


That’s to be expected when using nonsense parameters. :wink: The pid will determine which IPC ‘server’ (or rather socket) to send to. ENOENT means the socket file does not exist.

Still, the node-ipc module might be the culprit here, though it should support OSX without any trouble.


fair point @bzee :smiley:

using the pid given by the process yields nothing (beyond some logs i added). So not really sure what could be going on there.

I’ll dig a bit deeper the morn (on japan time now, so soon to bed). If you, @bzee or @happybeing have any more ideas of what to scope out let me know.


It’s an interesting exercise to think about possible issues without debugging! :slight_smile:

I assume the /tmp/app.<pid> file is created and the IPC server is effectively listening. Then the problem must be with the client, so I think you’re looking in the right direction @joshuef.

Perhaps try delaying the spawned process to see the actual output of the IPC client (not exiting immediately here: On Windows I usually see a glimpse of the Node script starting in a CMD and then disappearing — do you see that too on OSX? I’m curious to know whether the scripts spawns and if so what the output is.


Haha, yeh. Tell me about it. That’s my windows debugging life. (aka appveyor hell :stuck_out_tongue: )

Anyway. Wee update: I can confirm after some deeper digging, that it’s not node-ipc or the sciprt itself. I got calls to the script to be picked up after logging the auth uri from the browser. (Which crashed the fuse script but… that’s another story. It did start doing things. :tada: )

So it seems there’s an issue with how the app is registering itself with the system. On osx, at least with fully fledged apps, to open them up via registered URI, a bundle id is needed. I’m not sure of the case for this w/r/t scripts/IPC etc. But it’s likely something around this. So I’ll be continuing my exploration form here tomorrow!


Coming back to this.

I think this is quite an interesting problem, we’ll be needing to tackle for scripts in general.

OSX needs an Info.plist for an application bundle to register custom URL handlers (touched on over here:

While with FUSE the final packaged app could have this… The bigger Q is ‘do we want scripts to be able to auth automagically’ (A: yes!). *

So how could we do that?

I think that we might be needing to pass another option at app instantiation… perhaps responseScript or some such (which would still just pass along the auth response URI instead of needing a custom protocol to be registered…)? @nbaksalyar @marcin not sure what yous would make of this (nor really if there’s some security implication vs requiring a custom protocol to be registered?).

Other options would be providing a UI to get a response from the authenticator (which could then be requested by the app, or set via ENV or some such). Less ideal UX imo, but another option…

  • For now a bonus log is on master for anyone wanting to get scripts going, with a yarn prod-dev from the safe_browser repo, you’ll be able to see/pull out the response url and manually trigger the script. Not ideal, but a workaround for now…


I’m not sure what ‘bonus log’ means, but I think it might be best to await the solution rather than tweak SAFE Drive for this workaround, as to work it needs a custom build of the browser (if I understand correctly).

Instead, for SAFE Drive we could look at bundling an Info.plist if that is as straightforward as it sounds. @Stout77, would you like to have a crack at this, starting with the link Josh provided and asking for help here as needed?

Thanks for looking at this @joshuef. Sounds like we can make progress now, and work with any broader solution once that has been designed.


I’ll be away for work a couple of days but I’ll give it a go later in the week/weekend; looks like I’ll have to do a bit of studying for this…


Heh, by ‘bonus log’, I just meant another console.log which outputs the uri that would be triggering auth.

For sure it’s not something to rely on, but if you were wanting to progress onto other OSX issues, this would unblock you.

Bundling info.plist as I understand requires an app bundle output as part of the packaging process. I don’t think you can simply add an info.plist and it all goes, sadly :frowning:.


No hurry, just good you fancy looking into it so update us / ask for help as and when.

I haven’t looked and will leave it to you look at the link and consider this… ask Josh for clarification on this etc:

Bundling info.plist as I understand requires an app bundle output as part of the packaging process. I don’t think you can simply add an info.plist and it all goes, sadly

Then we can discuss ways to move this forward, and if you are the person doing so you get to choose :slight_smile:

Thanks again @joshuef I expect we’ll be back for more!


Considering we don’t have an app bundle, I wouldn’t know how to proceed with the info.plist option.
So I went ahead and compiled safebrowser as per


  • git clone
  • cd safe_browser
  • NODE_ENV=dev yarn
  • yarn rebuild

And then

  • yarn put-live-net-files-for-osx
  • yarn prod-dev

this launches the safe browser with additional infos in the console;
then is a separate terminal, in safenetwork-fuse/ :

DEBUG=safe-fuse*,safenetworkjs* node bin.js

app seems to authenticate (as before), output in the console is:

renderer.js:34 [15:04:09.264] Handling safe-auth: url
renderer.js:34 [15:04:09.298] Authenticator.js decoded authReq result:  { authReq: 
   { app: 
      { id: 'safenetwork-fuse',
        name: 'SAFE Network FUSE',
        scope: null,
        vendor: 'theWebalyst' },
     app_container: false,
     containers: [ [Object], [Object] ],
     containers_cap: 2,
     containers_len: 2 },
  reqId: 1566358583 }
renderer.js:34 [15:04:10.833] IPC.js: another response being parsed.: { error: null,
   { authReq: 
      { app: [Object],
        app_container: false,
        containers: [Array],
        containers_cap: 2,
        containers_len: 2 },
     isAuthorised: true,
     reqId: 1566358583 },
  type: 'DESKTOP',
renderer.js:34 [15:04:10.838] Listener for addAuthNotification
renderer.js:34 [15:04:18.769] Listener for addAuthNotification
renderer.js:34 [15:04:18.770] success happeninng
renderer.js:34 [15:04:18.770] IPC.js: Sending auth response true { authReq: 
   { app: 
      { id: 'safenetwork-fuse',
        name: 'SAFE Network FUSE',
        scope: null,
        vendor: 'theWebalyst' },
     app_container: false,
     containers: [ [Object], [Object] ],
     containers_cap: 2,
     containers_len: 2 },
  isAuthorised: true,
  reqId: 1566358583 }
renderer.js:34 [15:04:18.771] IPC.js: onAuthDecision running... { authReq: 
   { app: 
      { id: 'safenetwork-fuse',
        name: 'SAFE Network FUSE',
        scope: null,
        vendor: 'theWebalyst' },
     app_container: false,
     containers: [ [Object], [Object] ],
     containers_cap: 2,
     containers_len: 2 },
  isAuthorised: true,
  reqId: 1566358583 } true
renderer.js:34 [15:04:18.772] authenticator.js: encoding auth response { authReq: 
   { app: 
      { id: 'safenetwork-fuse',
        name: 'SAFE Network FUSE',
        scope: null,
        vendor: 'theWebalyst' },
     app_container: false,
     containers: [ [Object], [Object] ],
     containers_cap: 2,
     containers_len: 2 },
  isAuthorised: true,
  reqId: 1566358583 } true
renderer.js:34 [15:04:21.755] authenticator.js: auth decision CB { 'ref.buffer': <Buffer@0x7f9e5e668140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> } true
renderer.js:34 [15:04:23.332] Remote Calling:  setAppListUpdateListener
renderer.js:34 [15:04:23.334] Handling remote call in extension { id: '0.3oh7xq7nxee',
  isListener: true,
  name: 'setAppListUpdateListener' }

@joshuef, is this what you meant? How can I manually trigger the script from here?