Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Tristan Cavelier
jio
Commits
cd5d8f0c
Commit
cd5d8f0c
authored
Oct 01, 2015
by
lucas.parsy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added cryptstorage with tests
parent
9d15334f
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
640 additions
and
258 deletions
+640
-258
Gruntfile.js
Gruntfile.js
+1
-0
src/jio.storage/cryptstorage.js
src/jio.storage/cryptstorage.js
+124
-258
test/jio.storage/cryptstorage.tests.js
test/jio.storage/cryptstorage.tests.js
+514
-0
test/tests.html
test/tests.html
+1
-0
No files found.
Gruntfile.js
View file @
cd5d8f0c
...
...
@@ -180,6 +180,7 @@ module.exports = function (grunt) {
'
src/jio.storage/memorystorage.js
'
,
'
src/jio.storage/localstorage.js
'
,
'
src/jio.storage/zipstorage.js
'
,
'
src/jio.storage/cryptstorage.js
'
,
'
src/jio.storage/dropboxstorage.js
'
,
'
src/jio.storage/davstorage.js
'
,
'
src/jio.storage/unionstorage.js
'
,
...
...
src/jio.storage/cryptstorage.js
View file @
cd5d8f0c
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global jIO: true, sjcl: true, $: true, setTimeout: true */
jIO
.
addStorage
(
'
crypt
'
,
function
(
spec
,
my
)
{
/*jslint todo: true*/
spec
=
spec
||
{};
var
that
=
my
.
basicStorage
(
spec
,
my
),
priv
=
{},
is_valid_storage
=
(
spec
.
storage
?
true
:
false
),
super_serialized
=
that
.
serialized
;
/*
* Copyright 2015, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
priv
.
username
=
spec
.
username
||
''
;
priv
.
password
=
spec
.
password
||
''
;
priv
.
sub_storage_spec
=
spec
.
storage
||
{
type
:
'
base
'
};
priv
.
sub_storage_string
=
JSON
.
stringify
(
priv
.
sub_storage_string
);
/*jslint nomen: true*/
/*global jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer*/
that
.
serialized
=
function
()
{
var
o
=
super_serialized
();
o
.
username
=
priv
.
username
;
o
.
password
=
priv
.
password
;
// TODO : unsecured !!!
o
.
storage
=
priv
.
sub_storage_string
;
return
o
;
};
(
function
(
jIO
,
RSVP
,
DOMException
,
Blob
)
{
"
use strict
"
;
// you the cryptography system used by this storage is AES-GCM.
// here is an example of how to generate a key.
// var key;
// crypto.subtle.generateKey({name: "AES-GCM",length: 256},
// (true), ["encrypt", "decrypt"])
// .then(function(res){key = res;});
// find more informations about this cryptography system on
// https://github.com/diafygi/webcrypto-examples#aes-gcm
/**
* The JIO Cryptography Storage extension
*
* @class CryptStorage
* @constructor
*/
var
MIME_TYPE
=
"
application/x-jio-aes-gcm-encryption
"
;
that
.
validateState
=
function
(
)
{
if
(
priv
.
username
&&
is_valid_storage
)
{
return
''
;
function
CryptStorage
(
spec
)
{
if
(
!
spec
.
key
||
typeof
spec
.
key
!==
"
object
"
)
{
throw
new
TypeError
(
"
'key' must be a CryptoKey object
"
)
;
}
return
'
Need at least two parameters: "username" and "storage".
'
;
};
this
.
_key
=
spec
.
key
;
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
}
// TODO : IT IS NOT SECURE AT ALL!
// WE MUST REWORK CRYPTED STORAGE!
priv
.
encrypt_param_object
=
{
"
iv
"
:
"
kaprWwY/Ucr7pumXoTHbpA
"
,
"
v
"
:
1
,
"
iter
"
:
1000
,
"
ks
"
:
256
,
"
ts
"
:
128
,
"
mode
"
:
"
ccm
"
,
"
adata
"
:
""
,
"
cipher
"
:
"
aes
"
,
"
salt
"
:
"
K4bmZG9d704
"
CryptStorage
.
prototype
.
get
=
function
()
{
return
this
.
_sub_storage
.
get
.
apply
(
this
.
_sub_storage
,
arguments
);
};
priv
.
decrypt_param_object
=
{
"
iv
"
:
"
kaprWwY/Ucr7pumXoTHbpA
"
,
"
ks
"
:
256
,
"
ts
"
:
128
,
"
salt
"
:
"
K4bmZG9d704
"
CryptStorage
.
prototype
.
post
=
function
()
{
return
this
.
_sub_storage
.
post
.
apply
(
this
.
_sub_storage
,
arguments
);
};
priv
.
encrypt
=
function
(
data
,
callback
)
{
// end with a callback in order to improve encrypt to an
// asynchronous encryption.
var
tmp
=
sjcl
.
encrypt
(
priv
.
username
+
'
:
'
+
priv
.
password
,
data
,
priv
.
encrypt_param_object
);
callback
(
JSON
.
parse
(
tmp
).
ct
);
CryptStorage
.
prototype
.
put
=
function
()
{
return
this
.
_sub_storage
.
put
.
apply
(
this
.
_sub_storage
,
arguments
);
};
priv
.
decrypt
=
function
(
data
,
callback
)
{
var
tmp
,
param
=
$
.
extend
(
true
,
{},
priv
.
decrypt_param_object
);
param
.
ct
=
data
||
''
;
param
=
JSON
.
stringify
(
param
);
try
{
tmp
=
sjcl
.
decrypt
(
priv
.
username
+
'
:
'
+
priv
.
password
,
param
);
}
catch
(
e
)
{
callback
({
status
:
403
,
statusText
:
'
Forbidden
'
,
error
:
'
forbidden
'
,
message
:
'
Unable to decrypt.
'
,
reason
:
'
unable to decrypt
'
});
return
;
}
callback
(
undefined
,
tmp
);
CryptStorage
.
prototype
.
remove
=
function
()
{
return
this
.
_sub_storage
.
remove
.
apply
(
this
.
_sub_storage
,
arguments
);
};
priv
.
newAsyncModule
=
function
()
{
var
async
=
{};
async
.
call
=
function
(
obj
,
function_name
,
arglist
)
{
obj
.
_wait
=
obj
.
_wait
||
{};
if
(
obj
.
_wait
[
function_name
])
{
obj
.
_wait
[
function_name
]
-=
1
;
return
function
()
{
return
;
};
}
// ok if undef or 0
arglist
=
arglist
||
[];
setTimeout
(
function
()
{
obj
[
function_name
].
apply
(
obj
[
function_name
],
arglist
);
});
};
async
.
neverCall
=
function
(
obj
,
function_name
)
{
obj
.
_wait
=
obj
.
_wait
||
{};
obj
.
_wait
[
function_name
]
=
-
1
;
};
async
.
wait
=
function
(
obj
,
function_name
,
times
)
{
obj
.
_wait
=
obj
.
_wait
||
{};
obj
.
_wait
[
function_name
]
=
times
;
};
async
.
end
=
function
()
{
async
.
call
=
function
()
{
return
;
};
};
return
async
;
CryptStorage
.
prototype
.
hasCapacity
=
function
()
{
return
this
.
_sub_storage
.
hasCapacity
.
apply
(
this
.
_sub_storage
,
arguments
);
};
that
.
post
=
function
(
command
)
{
that
.
put
(
command
);
CryptStorage
.
prototype
.
buildQuery
=
function
()
{
return
this
.
_sub_storage
.
buildQuery
.
apply
(
this
.
_sub_storage
,
arguments
);
};
/**
* Saves a document.
* @method put
*/
that
.
put
=
function
(
command
)
{
var
new_file_name
,
new_file_content
,
am
=
priv
.
newAsyncModule
(),
o
=
{};
o
.
encryptFilePath
=
function
()
{
priv
.
encrypt
(
command
.
getDocId
(),
function
(
res
)
{
new_file_name
=
res
;
am
.
call
(
o
,
'
save
'
);
});
};
o
.
encryptFileContent
=
function
()
{
priv
.
encrypt
(
command
.
getDocContent
(),
function
(
res
)
{
new_file_content
=
res
;
am
.
call
(
o
,
'
save
'
);
});
};
o
.
save
=
function
()
{
var
success
=
function
(
val
)
{
val
.
id
=
command
.
getDocId
();
that
.
success
(
val
);
},
error
=
function
(
err
)
{
that
.
error
(
err
);
},
cloned_doc
=
command
.
cloneDoc
();
cloned_doc
.
_id
=
new_file_name
;
cloned_doc
.
content
=
new_file_content
;
that
.
addJob
(
'
put
'
,
priv
.
sub_storage_spec
,
cloned_doc
,
command
.
cloneOption
(),
success
,
error
);
};
am
.
wait
(
o
,
'
save
'
,
1
);
am
.
call
(
o
,
'
encryptFilePath
'
);
am
.
call
(
o
,
'
encryptFileContent
'
);
};
// end put
CryptStorage
.
prototype
.
putAttachment
=
function
(
id
,
name
,
blob
)
{
var
iv
=
crypto
.
getRandomValues
(
new
Uint8Array
(
12
)),
that
=
this
;
/**
* Loads a document.
* @method get
*/
that
.
get
=
function
(
command
)
{
var
new_file_name
,
am
=
priv
.
newAsyncModule
(),
o
=
{};
o
.
encryptFilePath
=
function
()
{
priv
.
encrypt
(
command
.
getDocId
(),
function
(
res
)
{
new_file_name
=
res
;
am
.
call
(
o
,
'
get
'
);
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsDataURL
(
blob
);
})
.
push
(
function
(
dataURL
)
{
//string->arraybuffer
var
strLen
=
dataURL
.
currentTarget
.
result
.
length
,
buf
=
new
ArrayBuffer
(
strLen
),
bufView
=
new
Uint8Array
(
buf
),
i
;
dataURL
=
dataURL
.
currentTarget
.
result
;
for
(
i
=
0
;
i
<
strLen
;
i
+=
1
)
{
bufView
[
i
]
=
dataURL
.
charCodeAt
(
i
);
}
return
crypto
.
subtle
.
encrypt
({
name
:
"
AES-GCM
"
,
iv
:
iv
},
that
.
_key
,
buf
);
})
.
push
(
function
(
coded
)
{
var
blob
=
new
Blob
([
iv
,
coded
],
{
type
:
MIME_TYPE
});
return
that
.
_sub_storage
.
putAttachment
(
id
,
name
,
blob
);
});
};
o
.
get
=
function
()
{
that
.
addJob
(
'
get
'
,
priv
.
sub_storage_spec
,
new_file_name
,
command
.
cloneOption
(),
o
.
success
,
o
.
error
);
};
o
.
success
=
function
(
val
)
{
val
.
_id
=
command
.
getDocId
();
if
(
command
.
getOption
(
'
metadata_only
'
))
{
that
.
success
(
val
);
}
else
{
priv
.
decrypt
(
val
.
content
,
function
(
err
,
res
)
{
if
(
err
)
{
that
.
error
(
err
);
}
else
{
val
.
content
=
res
;
that
.
success
(
val
);
}
});
}
};
o
.
error
=
function
(
error
)
{
that
.
error
(
error
);
};
am
.
call
(
o
,
'
encryptFilePath
'
);
};
// end get
};
/**
* Gets a document list.
* @method allDocs
*/
that
.
allDocs
=
function
(
command
)
{
var
result_array
=
[],
am
=
priv
.
newAsyncModule
(),
o
=
{};
o
.
allDocs
=
function
()
{
that
.
addJob
(
'
allDocs
'
,
priv
.
sub_storage_spec
,
null
,
command
.
cloneOption
(),
o
.
onSuccess
,
o
.
error
);
};
o
.
onSuccess
=
function
(
val
)
{
if
(
val
.
total_rows
===
0
)
{
return
am
.
call
(
o
,
'
success
'
);
}
result_array
=
val
.
rows
;
var
i
,
decrypt
=
function
(
c
)
{
priv
.
decrypt
(
result_array
[
c
].
id
,
function
(
err
,
res
)
{
if
(
err
)
{
am
.
call
(
o
,
'
error
'
,
[
err
]);
}
else
{
result_array
[
c
].
id
=
res
;
result_array
[
c
].
key
=
res
;
am
.
call
(
o
,
'
success
'
);
}
});
if
(
!
command
.
getOption
(
'
metadata_only
'
))
{
priv
.
decrypt
(
result_array
[
c
].
value
.
content
,
CryptStorage
.
prototype
.
getAttachment
=
function
(
id
,
name
)
{
var
that
=
this
;
return
that
.
_sub_storage
.
getAttachment
(
id
,
name
)
.
push
(
function
(
blob
)
{
if
(
blob
.
type
!==
MIME_TYPE
)
{
return
blob
;
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
})
.
push
(
function
(
coded
)
{
var
iv
;
function
(
err
,
res
)
{
if
(
err
)
{
am
.
call
(
o
,
'
error
'
,
[
err
]);
}
else
{
result_array
[
c
].
value
.
content
=
res
;
am
.
call
(
o
,
'
success
'
);
coded
=
coded
.
currentTarget
.
result
;
iv
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
iv
},
that
.
_key
,
coded
.
slice
(
12
));
})
.
push
(
function
(
arr
)
{
//arraybuffer->string
arr
=
String
.
fromCharCode
.
apply
(
null
,
new
Uint8Array
(
arr
));
try
{
return
jIO
.
util
.
dataURItoBlob
(
arr
);
}
catch
(
error
)
{
if
(
error
instanceof
DOMException
)
{
return
blob
;
}
throw
error
;
}
);
}
};
if
(
command
.
getOption
(
'
metadata_only
'
))
{
am
.
wait
(
o
,
'
success
'
,
val
.
total_rows
-
1
);
}
else
{
am
.
wait
(
o
,
'
success
'
,
val
.
total_rows
*
2
-
1
);
}
for
(
i
=
0
;
i
<
result_array
.
length
;
i
+=
1
)
{
decrypt
(
i
);
}
};
o
.
error
=
function
(
error
)
{
am
.
end
();
that
.
error
(
error
);
};
o
.
success
=
function
()
{
am
.
end
();
that
.
success
({
total_rows
:
result_array
.
length
,
rows
:
result_array
});
});
};
am
.
call
(
o
,
'
allDocs
'
);
};
// end allDocs
};
/**
* Removes a document.
* @method remove
*/
that
.
remove
=
function
(
command
)
{
var
new_file_name
,
o
=
{};
o
.
encryptDocId
=
function
()
{
priv
.
encrypt
(
command
.
getDocId
(),
function
(
res
)
{
new_file_name
=
res
;
o
.
removeDocument
();
});
};
o
.
removeDocument
=
function
()
{
var
cloned_doc
=
command
.
cloneDoc
();
cloned_doc
.
_id
=
new_file_name
;
that
.
addJob
(
'
remove
'
,
priv
.
sub_storage_spec
,
cloned_doc
,
command
.
cloneOption
(),
o
.
success
,
that
.
error
);
};
o
.
success
=
function
(
val
)
{
val
.
id
=
command
.
getDocId
();
that
.
success
(
val
);
};
o
.
encryptDocId
();
};
// end remove
CryptStorage
.
prototype
.
removeAttachment
=
function
()
{
return
this
.
_sub_storage
.
removeAttachment
.
apply
(
this
.
_sub_storage
,
arguments
);
};
CryptStorage
.
prototype
.
allAttachments
=
function
()
{
return
this
.
_sub_storage
.
allAttachments
.
apply
(
this
.
_sub_storage
,
arguments
);
};
jIO
.
addStorage
(
'
crypt
'
,
CryptStorage
);
return
that
;
});
}(
jIO
,
RSVP
,
DOMException
,
Blob
));
test/jio.storage/cryptstorage.tests.js
0 → 100644
View file @
cd5d8f0c
/*jslint nomen: true*/
/*global Blob, crypto, Uint8Array, ArrayBuffer*/
(
function
(
jIO
,
QUnit
,
Blob
)
{
"
use strict
"
;
var
test
=
QUnit
.
test
,
stop
=
QUnit
.
stop
,
start
=
QUnit
.
start
,
ok
=
QUnit
.
ok
,
expect
=
QUnit
.
expect
,
deepEqual
=
QUnit
.
deepEqual
,
equal
=
QUnit
.
equal
,
throws
=
QUnit
.
throws
,
module
=
QUnit
.
module
,
key
;
crypto
.
subtle
.
importKey
(
"
jwk
"
,
{
kty
:
"
oct
"
,
k
:
"
L6hUS9PdMP5AIxXyiFM0GOBukp0heD5wHPRctvWBcVg
"
,
alg
:
"
A256GCM
"
,
ext
:
true
},
{
name
:
"
AES-GCM
"
},
true
,
[
"
encrypt
"
,
"
decrypt
"
]
)
.
then
(
function
(
res
)
{
key
=
res
;
});
/////////////////////////////////////////////////////////////////
// Custom test substorage definition
/////////////////////////////////////////////////////////////////
function
Storage200
()
{
return
this
;
}
jIO
.
addStorage
(
'
cryptstorage200
'
,
Storage200
);
/////////////////////////////////////////////////////////////////
// CryptStorage.constructor
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.constructor
"
);
test
(
"
create substorage
"
,
function
()
{
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
equal
(
jio
.
__type
,
"
crypt
"
);
equal
(
jio
.
__storage
.
_sub_storage
.
__type
,
"
cryptstorage200
"
);
});
/////////////////////////////////////////////////////////////////
// CryptStorage.get
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.get
"
);
test
(
"
get called substorage get
"
,
function
()
{
stop
();
expect
(
2
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
get
=
function
(
id
)
{
equal
(
id
,
"
bar
"
,
"
get 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
get
(
"
bar
"
)
.
then
(
function
(
result
)
{
deepEqual
(
result
,
{
"
title
"
:
"
foo
"
},
"
Check document
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.post
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.post
"
);
test
(
"
post called substorage post
"
,
function
()
{
stop
();
expect
(
2
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
post
=
function
(
id
)
{
equal
(
id
,
"
bar
"
,
"
post 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
post
(
"
bar
"
)
.
then
(
function
(
result
)
{
deepEqual
(
result
,
{
"
title
"
:
"
foo
"
},
"
Check document
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.put
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.put
"
);
test
(
"
put called substorage put
"
,
function
()
{
stop
();
expect
(
2
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
put
=
function
(
id
)
{
equal
(
id
,
"
bar
"
,
"
put 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
put
(
"
bar
"
)
.
then
(
function
(
result
)
{
equal
(
result
,
"
bar
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.remove
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.remove
"
);
test
(
"
remove called substorage remove
"
,
function
()
{
stop
();
expect
(
2
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
remove
=
function
(
id
)
{
equal
(
id
,
"
bar
"
,
"
remove 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
remove
(
"
bar
"
)
.
then
(
function
(
result
)
{
equal
(
result
,
"
bar
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.hasCapacity
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.hasCapacity
"
);
test
(
"
hasCapacity return substorage value
"
,
function
()
{
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
delete
Storage200
.
prototype
.
hasCapacity
;
throws
(
function
()
{
jio
.
hasCapacity
(
"
foo
"
);
},
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
);
equal
(
error
.
status_code
,
501
);
equal
(
error
.
message
,
"
Capacity 'foo' is not implemented on 'cryptstorage200'
"
);
return
true
;
}
);
});
/////////////////////////////////////////////////////////////////
// CryptStorage.buildQuery
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.buildQuery
"
);
test
(
"
buildQuery called substorage buildQuery
"
,
function
()
{
stop
();
expect
(
2
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
buildQuery
=
function
(
id
)
{
equal
(
id
,
"
bar
"
,
"
buildQuery 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
buildQuery
(
"
bar
"
)
.
then
(
function
(
result
)
{
deepEqual
(
result
,
{
"
title
"
:
"
foo
"
},
"
Check document
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.removeAttachment
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.removeAttachment
"
);
test
(
"
removeAttachment called substorage removeAttachment
"
,
function
()
{
stop
();
expect
(
3
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
removeAttachment
=
function
(
id
,
name
)
{
equal
(
id
,
"
bar
"
,
"
removeAttachment 200 called
"
);
equal
(
name
,
"
foo
"
,
"
removeAttachment 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
removeAttachment
(
"
bar
"
,
"
foo
"
)
.
then
(
function
(
result
)
{
deepEqual
(
result
,
{
"
title
"
:
"
foo
"
},
"
Check document
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.allAttachments
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.allAttachments
"
);
test
(
"
allAttachments called substorage allAttachments
"
,
function
()
{
stop
();
expect
(
2
);
var
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
Storage200
.
prototype
.
allAttachments
=
function
(
id
)
{
equal
(
id
,
"
bar
"
,
"
allAttachments 200 called
"
);
return
{
title
:
"
foo
"
};
};
jio
.
allAttachments
(
"
bar
"
)
.
then
(
function
(
result
)
{
deepEqual
(
result
,
{
"
title
"
:
"
foo
"
},
"
Check document
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.getAttachment
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.getAttachment
"
,
{
setup
:
function
()
{
this
.
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
}
});
test
(
"
return substorage getattachment
"
,
function
()
{
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
blob
=
new
Blob
([
'
foo
'
]);
Storage200
.
prototype
.
getAttachment
=
function
(
arg1
,
arg2
)
{
equal
(
arg1
,
id
,
"
getAttachment 200 called
"
);
equal
(
arg2
,
attachment
,
"
getAttachment 200 called
"
);
return
blob
;
};
stop
();
expect
(
3
);
this
.
jio
.
getAttachment
(
id
,
attachment
)
.
then
(
function
(
result
)
{
equal
(
result
,
blob
,
"
Return substorage result
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
test
(
"
return substorage getattachment if decrypt fails
"
,
function
()
{
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
blob
=
new
Blob
([
'
foo
'
],
{
type
:
'
application/x-jio-aes-gcm-encryption
'
});
Storage200
.
prototype
.
getAttachment
=
function
(
arg1
,
arg2
)
{
equal
(
arg1
,
id
,
"
getAttachment 200 called
"
);
equal
(
arg2
,
attachment
,
"
getAttachment 200 called
"
);
return
blob
;
};
stop
();
expect
(
3
);
this
.
jio
.
getAttachment
(
id
,
attachment
)
.
then
(
function
(
result
)
{
equal
(
result
,
blob
,
"
Return substorage result
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
test
(
"
return substorage getattachment if not data url
"
,
function
()
{
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
blob
=
new
Blob
([
'
foo
'
],
{
type
:
'
application/x-jio-aes-gcm-encryption
'
});
Storage200
.
prototype
.
getAttachment
=
function
(
arg1
,
arg2
)
{
equal
(
arg1
,
id
,
"
getAttachment 200 called
"
);
equal
(
arg2
,
attachment
,
"
getAttachment 200 called
"
);
return
blob
;
};
stop
();
expect
(
3
);
this
.
jio
.
getAttachment
(
id
,
attachment
)
.
then
(
function
(
result
)
{
equal
(
result
,
blob
,
"
Return substorage result
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
test
(
"
decrypt blob from aes-gcm
"
,
function
()
{
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
value
=
"
azertyuio
\n
pàç_è-('é&
"
,
tocheck
=
"
data:application/x-jio-aes-gcm-encryption;base64,L3
"
+
"
LcvzpAlxu8/xd0fW7lPHZs5AP0ncexWoTfH57PCVkvrtp1JoB
"
+
"
wDzUYO+DHsfjAkzXkxhHHNUmxAtDiiSkRSvcbderS9FfIC7U6
"
+
"
KoGcqiP3OkEseL9Rd7F+qBwGuuDJyg==
"
,
blob
=
jIO
.
util
.
dataURItoBlob
(
tocheck
);
Storage200
.
prototype
.
getAttachment
=
function
(
arg1
,
arg2
)
{
equal
(
arg1
,
id
,
"
getAttachment 200 called
"
);
equal
(
arg2
,
attachment
,
"
getAttachment 200 called
"
);
return
blob
;
};
stop
();
expect
(
6
);
this
.
jio
.
getAttachment
(
id
,
attachment
)
.
then
(
function
(
result
)
{
ok
(
result
!==
blob
,
"
Does not return substorage result
"
);
ok
(
result
instanceof
Blob
,
"
Data is Blob
"
);
deepEqual
(
result
.
type
,
"
text/plain;charset=utf-8
"
,
"
Check mimetype
"
);
return
jIO
.
util
.
readBlobAsText
(
result
);
})
.
then
(
function
(
result
)
{
equal
(
result
.
target
.
result
,
value
,
"
Attachment correctly fetched
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
/////////////////////////////////////////////////////////////////
// CryptStorage.putAttachment
/////////////////////////////////////////////////////////////////
module
(
"
CryptStorage.putAttachment
"
,
{
setup
:
function
()
{
this
.
jio
=
jIO
.
createJIO
({
type
:
"
crypt
"
,
key
:
key
,
sub_storage
:
{
type
:
"
cryptstorage200
"
}
});
}
});
function
decodeAES
(
blob
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
})
.
push
(
function
(
coded
)
{
var
iv
;
coded
=
coded
.
currentTarget
.
result
;
iv
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
iv
},
key
,
coded
.
slice
(
12
));
})
.
push
(
function
(
arr
)
{
arr
=
String
.
fromCharCode
.
apply
(
null
,
new
Uint8Array
(
arr
));
equal
(
arr
,
"
data:text/foo;base64,YXplcnR5dWlvCnDDoMOnX8OoLSgnw6km
"
,
"
Attachment correctly crypted
"
);
return
"
ok
"
;
});
}
test
(
"
crypt blob to aes-gcm
"
,
function
()
{
var
id
=
"
/
"
,
attachment
=
"
stringattachment
"
,
value
=
"
azertyuio
\n
pàç_è-('é&
"
,
blob
=
new
Blob
([
value
],
{
type
:
'
text/foo
'
});
Storage200
.
prototype
.
putAttachment
=
function
(
arg1
,
arg2
,
arg3
)
{
equal
(
arg1
,
id
,
"
putAttachment 200 called
"
);
equal
(
arg2
,
attachment
,
"
putAttachment 200 called
"
);
ok
(
true
,
arg3
!==
blob
,
"
putAttachment 200 called
"
);
ok
(
arg3
instanceof
Blob
,
"
Data is Blob
"
);
equal
(
arg3
.
type
,
"
application/x-jio-aes-gcm-encryption
"
,
"
Check mimetype
"
);
return
decodeAES
(
arg3
);
};
stop
();
expect
(
7
);
this
.
jio
.
putAttachment
(
id
,
attachment
,
blob
)
.
then
(
function
(
result
)
{
equal
(
result
,
"
ok
"
,
"
Return substorage result
"
);
})
.
fail
(
function
(
error
)
{
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
}(
jIO
,
QUnit
,
Blob
));
test/tests.html
View file @
cd5d8f0c
...
...
@@ -42,6 +42,7 @@
<script
src=
"jio.storage/shastorage.tests.js"
></script>
<!--script src="jio.storage/indexstorage.tests.js"></script-->
<script
src=
"jio.storage/cryptstorage.tests.js"
></script>
<script
src=
"jio.storage/dropboxstorage.tests.js"
></script>
<script
src=
"jio.storage/zipstorage.tests.js"
></script>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment