@ -86,47 +86,122 @@ var createLoginBlockPath = function (Env, publicKey) { // FIXME BLOCKS
return Path . join ( Env . paths . block , safeKey . slice ( 0 , 2 ) , safeKey ) ;
} ;
Block . writeLoginBlock = function ( Env , safeKey , msg , cb ) { // FIXME BLOCKS
Block . validateAncestorProof = function ( Env , proof , _cb ) {
var cb = Util . once ( Util . mkAsync ( _cb ) ) ;
/* prove that you own an existing block by signing for its publicKey */
try {
var parsed = JSON . parse ( proof ) ;
var pub = parsed [ 0 ] ;
var u8 _pub = Nacl . util . decodeBase64 ( pub ) ;
var sig = parsed [ 1 ] ;
var u8 _sig = Nacl . util . decodeBase64 ( sig ) ;
var valid = false ;
nThen ( function ( w ) {
valid = Nacl . sign . detached . verify ( u8 _pub , u8 _sig , u8 _pub ) ;
if ( ! valid ) {
w . abort ( ) ;
return void cb ( 'E_INVALID_ANCESTOR_PROOF' ) ;
}
// else fall through to next step
} ) . nThen ( function ( w ) {
var path = createLoginBlockPath ( Env , pub ) ;
Fs . access ( path , Fs . constants . F _OK , w ( function ( err ) {
if ( ! err ) { return ; }
w . abort ( ) ; // else
return void cb ( "E_MISSING_ANCESTOR" ) ;
} ) ) ;
} ) . nThen ( function ( ) {
cb ( void 0 , pub ) ;
} ) ;
} catch ( err ) {
return void cb ( err ) ;
}
} ;
Block . writeLoginBlock = function ( Env , safeKey , msg , _cb ) { // FIXME BLOCKS
var cb = Util . once ( Util . mkAsync ( _cb ) ) ;
//console.log(msg);
var publicKey = msg [ 0 ] ;
var signature = msg [ 1 ] ;
var block = msg [ 2 ] ;
validateLoginBlock ( Env , publicKey , signature , block , function ( e , validatedBlock ) {
if ( e ) { return void cb ( e ) ; }
if ( ! ( validatedBlock instanceof Uint8Array ) ) { return void cb ( 'E_INVALID_BLOCK' ) ; }
// derive the filepath
var path = createLoginBlockPath ( Env , publicKey ) ;
// make sure the path is valid
if ( typeof ( path ) !== 'string' ) {
return void cb ( 'E_INVALID_BLOCK_PATH' ) ;
var registrationProof = msg [ 3 ] ;
var previousKey ;
var validatedBlock , parsed , path ;
nThen ( function ( w ) {
if ( Util . escapeKeyCharacters ( publicKey ) !== safeKey ) {
w . abort ( ) ;
return void cb ( "INCORRECT_KEY" ) ;
}
var parsed = Path . parse ( path ) ;
if ( ! parsed || typeof ( parsed . dir ) !== 'string' ) {
return void cb ( "E_INVALID_BLOCK_PATH_2" ) ;
} ) . nThen ( function ( w ) {
if ( ! Env . restrictRegistration ) { return ; }
if ( ! registrationProof ) {
// we allow users with existing blocks to create new ones
// call back with error if registration is restricted and no proof of an existing block was provided
w . abort ( ) ;
Env . Log . info ( "BLOCK_REJECTED_REGISTRATION" , {
safeKey : safeKey ,
publicKey : publicKey ,
} ) ;
return cb ( "E_RESTRICTED" ) ;
}
nThen ( function ( w ) {
// make sure the path to the file exists
Fse . mkdirp ( parsed . dir , w ( function ( e ) {
if ( e ) {
w . abort ( ) ;
cb ( e ) ;
}
} ) ) ;
} ) . nThen ( function ( ) {
// actually write the block
// flow is dumb and I need to guard against this which will never happen
/*:: if (typeof(validatedBlock) === 'undefined') { throw new Error('should never happen'); } */
/*:: if (typeof(path) === 'undefined') { throw new Error('should never happen'); } */
Fs . writeFile ( path , Buffer . from ( validatedBlock ) , { encoding : "binary" , } , function ( err ) {
if ( err ) { return void cb ( err ) ; }
cb ( ) ;
Env . validateAncestorProof ( registrationProof , w ( function ( err , provenKey ) {
if ( err || ! provenKey ) { // double check that a key was validated
w . abort ( ) ;
Env . Log . warn ( 'BLOCK_REJECTED_INVALID_ANCESTOR' , {
error : err ,
} ) ;
return void cb ( "E_RESTRICTED" ) ;
}
previousKey = provenKey ;
} ) ) ;
} ) . nThen ( function ( w ) {
validateLoginBlock ( Env , publicKey , signature , block , w ( function ( e , _validatedBlock ) {
if ( e ) {
w . abort ( ) ;
return void cb ( e ) ;
}
if ( ! ( _validatedBlock instanceof Uint8Array ) ) {
w . abort ( ) ;
return void cb ( 'E_INVALID_BLOCK' ) ;
}
validatedBlock = _validatedBlock ;
// derive the filepath
path = createLoginBlockPath ( Env , publicKey ) ;
// make sure the path is valid
if ( typeof ( path ) !== 'string' ) {
return void cb ( 'E_INVALID_BLOCK_PATH' ) ;
}
parsed = Path . parse ( path ) ;
if ( ! parsed || typeof ( parsed . dir ) !== 'string' ) {
w . abort ( ) ;
return void cb ( "E_INVALID_BLOCK_PATH_2" ) ;
}
} ) ) ;
} ) . nThen ( function ( w ) {
// make sure the path to the file exists
Fse . mkdirp ( parsed . dir , w ( function ( e ) {
if ( e ) {
w . abort ( ) ;
cb ( e ) ;
}
} ) ) ;
} ) . nThen ( function ( ) {
// actually write the block
Fs . writeFile ( path , Buffer . from ( validatedBlock ) , { encoding : "binary" , } , function ( err ) {
if ( err ) { return void cb ( err ) ; }
Env . Log . info ( 'BLOCK_WRITE_BY_OWNER' , {
safeKey : safeKey ,
blockId : publicKey ,
isChange : Boolean ( registrationProof ) ,
previousKey : previousKey ,
path : path ,
} ) ;
cb ( ) ;
} ) ;
} ) ;
} ;
@ -146,26 +221,33 @@ Block.removeLoginBlock = function (Env, safeKey, msg, cb) { // FIXME BLOCKS
var signature = msg [ 1 ] ;
var block = Nacl . util . decodeUTF8 ( 'DELETE_BLOCK' ) ; // clients and the server will have to agree on this constant
validateLoginBlock ( Env , publicKey , signature , block , function ( e /*::, validatedBlock */ ) {
if ( e ) { return void cb ( e ) ; }
// derive the filepath
var path = createLoginBlockPath ( Env , publicKey ) ;
// make sure the path is valid
if ( typeof ( path ) !== 'string' ) {
return void cb ( 'E_INVALID_BLOCK_PATH' ) ;
nThen ( function ( w ) {
if ( Util . escapeKeyCharacters ( publicKey ) !== safeKey ) {
w . abort ( ) ;
return void cb ( "INCORRECT_KEY" ) ;
}
} ) . nThen ( function ( ) {
validateLoginBlock ( Env , publicKey , signature , block , function ( e /*::, validatedBlock */ ) {
if ( e ) { return void cb ( e ) ; }
// derive the filepath
var path = createLoginBlockPath ( Env , publicKey ) ;
// make sure the path is valid
if ( typeof ( path ) !== 'string' ) {
return void cb ( 'E_INVALID_BLOCK_PATH' ) ;
}
// FIXME COLDSTORAGE
Fs . unlink ( path , function ( err ) {
Env . Log . info ( 'DELETION_BLOCK_BY_OWNER_RPC' , {
publicKey : publicKey ,
path : path ,
status : err ? String ( err ) : 'SUCCESS' ,
} ) ;
// FIXME COLDSTORAGE
Fs . unlink ( path , function ( err ) {
Env . Log . info ( 'DELETION_BLOCK_BY_OWNER_RPC' , {
publicKey : publicKey ,
path : path ,
status : err ? String ( err ) : 'SUCCESS' ,
if ( err ) { return void cb ( err ) ; }
cb ( ) ;
} ) ;
if ( err ) { return void cb ( err ) ; }
cb ( ) ;
} ) ;
} ) ;
} ;