Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio_mebibou
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
Alexandra Rogova
jio_mebibou
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
Show 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) {
...
@@ -180,6 +180,7 @@ module.exports = function (grunt) {
'
src/jio.storage/memorystorage.js
'
,
'
src/jio.storage/memorystorage.js
'
,
'
src/jio.storage/localstorage.js
'
,
'
src/jio.storage/localstorage.js
'
,
'
src/jio.storage/zipstorage.js
'
,
'
src/jio.storage/zipstorage.js
'
,
'
src/jio.storage/cryptstorage.js
'
,
'
src/jio.storage/dropboxstorage.js
'
,
'
src/jio.storage/dropboxstorage.js
'
,
'
src/jio.storage/davstorage.js
'
,
'
src/jio.storage/davstorage.js
'
,
'
src/jio.storage/unionstorage.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 */
* Copyright 2015, Nexedi SA
jIO
.
addStorage
(
'
crypt
'
,
function
(
spec
,
my
)
{
* Released under the LGPL license.
/*jslint todo: true*/
* http://www.gnu.org/licenses/lgpl.html
spec
=
spec
||
{};
*/
var
that
=
my
.
basicStorage
(
spec
,
my
),
priv
=
{},
is_valid_storage
=
(
spec
.
storage
?
true
:
false
),
super_serialized
=
that
.
serialized
;
priv
.
username
=
spec
.
username
||
''
;
/*jslint nomen: true*/
priv
.
password
=
spec
.
password
||
''
;
/*global jIO, RSVP, DOMException, Blob, crypto, Uint8Array, ArrayBuffer*/
priv
.
sub_storage_spec
=
spec
.
storage
||
{
type
:
'
base
'
};
priv
.
sub_storage_string
=
JSON
.
stringify
(
priv
.
sub_storage_string
);
that
.
serialized
=
function
()
{
(
function
(
jIO
,
RSVP
,
DOMException
,
Blob
)
{
var
o
=
super_serialized
();
"
use strict
"
;
o
.
username
=
priv
.
username
;
o
.
password
=
priv
.
password
;
// TODO : unsecured !!!
o
.
storage
=
priv
.
sub_storage_string
;
return
o
;
};
that
.
validateState
=
function
()
{
if
(
priv
.
username
&&
is_valid_storage
)
{
return
''
;
}
return
'
Need at least two parameters: "username" and "storage".
'
;
};
// TODO : IT IS NOT SECURE AT ALL!
// you the cryptography system used by this storage is AES-GCM.
// WE MUST REWORK CRYPTED STORAGE!
// here is an example of how to generate a key.
priv
.
encrypt_param_object
=
{
"
iv
"
:
"
kaprWwY/Ucr7pumXoTHbpA
"
,
"
v
"
:
1
,
"
iter
"
:
1000
,
"
ks
"
:
256
,
"
ts
"
:
128
,
"
mode
"
:
"
ccm
"
,
"
adata
"
:
""
,
"
cipher
"
:
"
aes
"
,
"
salt
"
:
"
K4bmZG9d704
"
};
priv
.
decrypt_param_object
=
{
"
iv
"
:
"
kaprWwY/Ucr7pumXoTHbpA
"
,
"
ks
"
:
256
,
"
ts
"
:
128
,
"
salt
"
:
"
K4bmZG9d704
"
};
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
);
};
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
);
};
priv
.
newAsyncModule
=
function
()
{
// var key;
var
async
=
{};
// crypto.subtle.generateKey({name: "AES-GCM",length: 256},
async
.
call
=
function
(
obj
,
function_name
,
arglist
)
{
// (true), ["encrypt", "decrypt"])
obj
.
_wait
=
obj
.
_wait
||
{};
// .then(function(res){key = res;});
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
;
};
that
.
post
=
function
(
command
)
{
// find more informations about this cryptography system on
that
.
put
(
command
);
// https://github.com/diafygi/webcrypto-examples#aes-gcm
};
/**
/**
* Saves a document.
* The JIO Cryptography Storage extension
* @method put
*
* @class CryptStorage
* @constructor
*/
*/
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
;
var
MIME_TYPE
=
"
application/x-jio-aes-gcm-encryption
"
;
cloned_doc
.
content
=
new_file_content
;
that
.
addJob
(
'
put
'
,
priv
.
sub_storage_spec
,
cloned_doc
,
function
CryptStorage
(
spec
)
{
command
.
cloneOption
(),
success
,
error
);
if
(
!
spec
.
key
||
typeof
spec
.
key
!==
"
object
"
)
{
throw
new
TypeError
(
"
'key' must be a CryptoKey object
"
);
}
this
.
_key
=
spec
.
key
;
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
}
CryptStorage
.
prototype
.
get
=
function
()
{
return
this
.
_sub_storage
.
get
.
apply
(
this
.
_sub_storage
,
arguments
);
};
};
am
.
wait
(
o
,
'
save
'
,
1
);
am
.
call
(
o
,
'
encryptFilePath
'
);
am
.
call
(
o
,
'
encryptFileContent
'
);
};
// end put
/**
CryptStorage
.
prototype
.
post
=
function
()
{
* Loads a document.
return
this
.
_sub_storage
.
post
.
apply
(
this
.
_sub_storage
,
* @method get
arguments
);
*/
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
'
);
});
};
};
o
.
get
=
function
()
{
that
.
addJob
(
'
get
'
,
priv
.
sub_storage_spec
,
new_file_name
,
CryptStorage
.
prototype
.
put
=
function
()
{
command
.
cloneOption
(),
o
.
success
,
o
.
error
);
return
this
.
_sub_storage
.
put
.
apply
(
this
.
_sub_storage
,
arguments
);
};
};
o
.
success
=
function
(
val
)
{
val
.
_id
=
command
.
getDocId
();
CryptStorage
.
prototype
.
remove
=
function
()
{
if
(
command
.
getOption
(
'
metadata_only
'
))
{
return
this
.
_sub_storage
.
remove
.
apply
(
this
.
_sub_storage
,
that
.
success
(
val
);
arguments
);
}
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
);
CryptStorage
.
prototype
.
hasCapacity
=
function
()
{
return
this
.
_sub_storage
.
hasCapacity
.
apply
(
this
.
_sub_storage
,
arguments
);
};
};
am
.
call
(
o
,
'
encryptFilePath
'
);
};
// end get
/**
CryptStorage
.
prototype
.
buildQuery
=
function
()
{
* Gets a document list.
return
this
.
_sub_storage
.
buildQuery
.
apply
(
this
.
_sub_storage
,
* @method allDocs
arguments
);
*/
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
'
);
CryptStorage
.
prototype
.
putAttachment
=
function
(
id
,
name
,
blob
)
{
}
var
iv
=
crypto
.
getRandomValues
(
new
Uint8Array
(
12
)),
result_array
=
val
.
rows
;
that
=
this
;
var
i
,
decrypt
=
function
(
c
)
{
priv
.
decrypt
(
result_array
[
c
].
id
,
function
(
err
,
res
)
{
return
new
RSVP
.
Queue
()
if
(
err
)
{
.
push
(
function
()
{
am
.
call
(
o
,
'
error
'
,
[
err
]);
return
jIO
.
util
.
readBlobAsDataURL
(
blob
);
}
else
{
})
result_array
[
c
].
id
=
res
;
.
push
(
function
(
dataURL
)
{
result_array
[
c
].
key
=
res
;
//string->arraybuffer
am
.
call
(
o
,
'
success
'
);
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
);
});
});
if
(
!
command
.
getOption
(
'
metadata_only
'
))
{
};
priv
.
decrypt
(
result_array
[
c
].
value
.
content
,
function
(
err
,
res
)
{
CryptStorage
.
prototype
.
getAttachment
=
function
(
id
,
name
)
{
if
(
err
)
{
var
that
=
this
;
am
.
call
(
o
,
'
error
'
,
[
err
]);
}
else
{
return
that
.
_sub_storage
.
getAttachment
(
id
,
name
)
result_array
[
c
].
value
.
content
=
res
;
.
push
(
function
(
blob
)
{
am
.
call
(
o
,
'
success
'
);
if
(
blob
.
type
!==
MIME_TYPE
)
{
}
return
blob
;
}
);
}
}
};
return
new
RSVP
.
Queue
()
if
(
command
.
getOption
(
'
metadata_only
'
))
{
.
push
(
function
()
{
am
.
wait
(
o
,
'
success
'
,
val
.
total_rows
-
1
);
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
}
else
{
})
am
.
wait
(
o
,
'
success
'
,
val
.
total_rows
*
2
-
1
);
.
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
},
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
;
}
}
for
(
i
=
0
;
i
<
result_array
.
length
;
i
+=
1
)
{
throw
error
;
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
();
CryptStorage
.
prototype
.
removeAttachment
=
function
()
{
cloned_doc
.
_id
=
new_file_name
;
return
this
.
_sub_storage
.
removeAttachment
.
apply
(
this
.
_sub_storage
,
that
.
addJob
(
'
remove
'
,
priv
.
sub_storage_spec
,
cloned_doc
,
arguments
);
command
.
cloneOption
(),
o
.
success
,
that
.
error
);
};
};
o
.
success
=
function
(
val
)
{
val
.
id
=
command
.
getDocId
();
CryptStorage
.
prototype
.
allAttachments
=
function
()
{
that
.
success
(
val
);
return
this
.
_sub_storage
.
allAttachments
.
apply
(
this
.
_sub_storage
,
arguments
);
};
};
o
.
encryptDocId
();
};
// end remove
return
that
;
jIO
.
addStorage
(
'
crypt
'
,
CryptStorage
);
});
}(
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 @@
...
@@ -42,6 +42,7 @@
<script
src=
"jio.storage/shastorage.tests.js"
></script>
<script
src=
"jio.storage/shastorage.tests.js"
></script>
<!--script src="jio.storage/indexstorage.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/dropboxstorage.tests.js"
></script>
<script
src=
"jio.storage/zipstorage.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