MaidSafe Dev Update :safe: 15th March 2016

No, no, no. It’s embrace, extend, and then extinguish. The order is extremely important.

1 Like

If there is problem with CORS I can address it quick. Will check this out. Also, I find that I missed to document on how to invoke from web browsers using the api.safenet instead of localhost:8100. I will make a quick sample and check this out.

That’s corrected in the document. Thanks :slight_smile:

5 Likes

Oh, very good! I was thinking before sleeping about whether there should be an alias URL which can just hit port 80 and achieve the same.

So, access isn’t be restricted by design (for security) at this phase?

Edit: BTW, the code I was working with was literally hacked together late last night from the examples, so there is a good chance the problem is my end! The message back looked like there was some security issue though.

No problem! :slight_smile:

BTW, the naming of the token variable changes between some examples too, which may throw some people.

It would be good to have a wee demo web app too somewhere, where all the source code was present and you could do the basics (authenticate, put a file, read a file, reuse existing session, etc). These sort of live examples are great for pulling apart and customising.

2 Likes

Thank You for all the effort!

So every Client/Vault will run it’s own STUN-Server? Is this a specialized version for P2P and anonymity?

More info on STUN for those interested. Link 1 and Link 2.

1 Like

Yes it is STUN like capabilities but not the STUN rfc we have implemented. More like echo servers (here is your external address and many of us can see it etc.) using a protocolMapper type (our type).

CRUST at the moment is not using authenticated encryption for serialisation. IT will though via the mio version which ensures no route poison attacks etc.

5 Likes

I’ve been reading through some of the API documentation and am finding it a bit hard to understand. A bit too much tech language and not enough defining of terms and examples/tutorials I think. I know it JUST came out and that’s awesome but some expounding would be good.

1 Like

Nice, looking great :smiley:

Trying to build against the launcher, I can already make connection with the launcher through the nodejs sample code and allow safe drive access, however it gives back this:

nodejs fetch.js

/home/test/safenetwork/node_modules/libsodium-wrappers/node_modules/libsodium/dist/modules/libsodium.js:14
aughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Mod
^
Error: auth() received invalid user or password
at Request.auth (/usr/lib/nodejs/request/index.js:1067:11)
at Request.init (/usr/lib/nodejs/request/index.js:310:10)
at new Request (/usr/lib/nodejs/request/index.js:124:8)
at Function.request [as get] (/usr/lib/nodejs/request/index.js:1279:11)
at Request.onAuthResponse [as _callback] (/home/test/safenetwork/fetch.js:98:15)
at Request.self.callback (/usr/lib/nodejs/request/index.js:148:22)
at Request.EventEmitter.emit (events.js:98:17)
at Request. (/usr/lib/nodejs/request/index.js:896:14)
at Request.EventEmitter.emit (events.js:117:20)
at IncomingMessage. (/usr/lib/nodejs/request/index.js:847:12)

I basically embedded the file fetch nodejs sample code within the auth post sample code callback. Not sure if I understand correctly but I would assume it should give the right user and password when authorized by the launcher?

Code listed below:

`// libsodium wrappers is used for crypto
var libsodium = require(‘libsodium-wrappers’);
var httpRequest = require(‘request’);

// Generate Assymetric Key pairs
var assymetricKeys = libsodium.crypto_box_keypair();
// Generate random Nonce
var nonce = libsodium.randombytes_buf(libsodium.crypto_box_NONCEBYTES);;

// Creating the authorisation request payload
var payload = {
app: {
name: ‘Demo App’,
version: ‘0.0.1’,
vendor: ‘maidsafe’,
id: ‘org.maidsafe.demo’
},
// Converting assymetric public key to base64 string
publicKey: new Buffer(assymetricKeys.publicKey).toString(‘base64’),
// Converting nonce to base64 string
nonce: new Buffer(nonce).toString(‘base64’),
// List of permissions requested
permissions: [‘SAFE_DRIVE_ACCESS’]
};

// Preparing the request object
var request = {
url: ‘http://localhost:8100/auth’,
headers: {
‘Content-Type’: ‘application/json’
},
json: payload
};

// Handle the response recieved from the launcher
var onAuthResponse = function(err, response) {
if (err) {
throw err;
}
if (response.statusCode !== 200) {
throw new Error('Failed with error code: ’ + response.statusCode);
}
// The encrypted symmetric key recieved as base64 string is converted to Uint8Array
var cipherText = new Uint8Array(new Buffer(response.body.encryptedKey, ‘base64’));
// The asymmetric public key of launcher recieved as base64 string is converted to Uint8Array
var publicKey = new Uint8Array(new Buffer(response.body.publicKey, ‘base64’));
// the cipher message is decrypted using the assymetric private key of application and the public key of launcher
var data = libsodium.crypto_box_open_easy(cipherText, nonce, publicKey, assymetricKeys.privateKey);
// The first segment of the data will have the symmetric key
var symetricKey = data.slice(0, libsodium.crypto_secretbox_KEYBYTES);
// The second segment of the data will have the nonce to be used
var symetricNonce = data.slice(libsodium.crypto_secretbox_KEYBYTES);
// Authorisation token
var token = response.body.token;
// List of persmissions approved by the user
var permissions = response.body.permissions;
// Creating the payload
var filePath = ‘/private/snapshot_blob.bin’;
var isPathShared = false;

// Change if the query parameters are to be sent
var appendQueryParams = false;

// Preparing the request options with the auth token
var request = {
url: ‘http://localhost:8100/nfs/file/’ + encodeURIComponent(filePath) + ‘/’ + isPathShared,
auth: {
bearer: token
}
};

// send query parameters
// The query parameters are encrypted
if (appendQueryParams) {
var queryParams = ‘offset=0’;
request.url += ‘?’;
var encryptedParams = libsodium.crypto_secretbox_easy(queryParams, symmetricNonce, symmetricKey).toString(‘base64’);
request.url += encryptedParams;
}

// Handling the response
var onResponse = function(err, res, body) {
if (err) {
return console.log(‘Err:’, err);
}
if (res.statusCode === 400) {
return console.log(‘Bad request’);
}
if (res.statusCode === 401) {
return console.log(‘Unauthorised’);
}
body = new Buffer(body, ‘base64’);
// Decrypt the file content
var decryptedData = libsodium.crypto_secretbox_open_easy(new Uint8Array(body), symmetricNonce, symmetricKey);
console.log(‘File Content:’, new Buffer(decryptedData).toString());
};
// Send get file request
httpRequest.get(request, onResponse);
};

// Sending authorisation request
httpRequest.post(request, onAuthResponse);

`

1 Like

I just ran the same code of yours and it works fine. I get an error response
{"errorCode":-1502,"description":"FfiError::PathNotFound"} because I don’t have the file. There was a typo in the variable naming though, corrected and pasted as a gist

But the typo has nothing to do with the error reported. I tested it on Windows. If you still have an issue, please pass on more info on the platform and the version of nodejs. We have developed and tested on 5.0 and above.

2 Likes

Thanks, works with the latest nodejs version upgrade!

3 Likes

Facebook, Twitter, Reddit, Instagram, Tumblr, Imgur, etc., etc.

1 Like

The potential for SAFE to be a Silicon Valley unicorn slayer is crazy…am I right!?:stuck_out_tongue_closed_eyes:

If it was me, I’d me nervous as hell right now if I was these guys…they are gonna wake up one day and be all like “Where did our metadata go?..SAFE what???..”

10 Likes

Krishna, did you get chance to look at this? I am thinking of having another play tonight!

1 Like

He should be asleep (India) but he works huge hours, I would say safe to play tonight and he will be around in about 7 hours or so, but ye never know :smiley:

3 Likes

Thanks, David. I ran my scripts as node.js and after some debugging, I managed to update a file and retrieve it again, which was pretty cool! However, browserify still resulted in CORS issues (with/without api.safenet as the URL), so it looks like the Access-Control-Allow-Headers will need setting to allow this.

4 Likes

I so hope this is opt-in. I wish the web proxy was too (granted it doesn’t do anything if you haven’t setup the PAC file)

Yes, a PR was merged yesterday and I did test the same using this sample. Can you please try with the latest master branch of launcher

5 Likes

BUG: After updating the maidsafe demo app, I no longer can access to my public ID. I had to create a new one.

2 Likes

I’m trying this but get an ‘FFI process terminated’ error when trying to launch the newly compiled version. I think I followed the instructions correctly, but I haven’t done anything with Rust for half a year or so, so I may be off somewhere. I’m running Win7 x64.

I grabbed x64 libsodium.a and set the environment variable to the corresponding directory
I made a release build of latest safe_ffi with Rust 1.7 (x64)
Copied the resulting safe_ffi.dll to safe_launcher-master\app\api\ffi
ran npm install and then npm run package

Hope you built latest ffi master branch against the mock - cargo build --relase --features use-mock-routing and placed the dll in the api/ffi folder of safe_launcher. Are my assumptions correct?

1 Like