Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
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
amrani
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) {
...
@@ -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
;
// you the cryptography system used by this storage is AES-GCM.
return
o
;
// 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
(
)
{
function
CryptStorage
(
spec
)
{
if
(
priv
.
username
&&
is_valid_storage
)
{
if
(
!
spec
.
key
||
typeof
spec
.
key
!==
"
object
"
)
{
return
''
;
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!
CryptStorage
.
prototype
.
get
=
function
()
{
// WE MUST REWORK CRYPTED STORAGE!
return
this
.
_sub_storage
.
get
.
apply
(
this
.
_sub_storage
,
priv
.
encrypt_param_object
=
{
arguments
);
"
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
"
,
CryptStorage
.
prototype
.
post
=
function
()
{
"
ks
"
:
256
,
return
this
.
_sub_storage
.
post
.
apply
(
this
.
_sub_storage
,
"
ts
"
:
128
,
arguments
);
"
salt
"
:
"
K4bmZG9d704
"
};
};
priv
.
encrypt
=
function
(
data
,
callback
)
{
// end with a callback in order to improve encrypt to an
CryptStorage
.
prototype
.
put
=
function
()
{
// asynchronous encryption.
return
this
.
_sub_storage
.
put
.
apply
(
this
.
_sub_storage
,
var
tmp
=
sjcl
.
encrypt
(
priv
.
username
+
'
:
'
+
priv
.
password
,
data
,
arguments
);
priv
.
encrypt_param_object
);
callback
(
JSON
.
parse
(
tmp
).
ct
);
};
};
priv
.
decrypt
=
function
(
data
,
callback
)
{
var
tmp
,
param
=
$
.
extend
(
true
,
{},
priv
.
decrypt_param_object
);
CryptStorage
.
prototype
.
remove
=
function
()
{
param
.
ct
=
data
||
''
;
return
this
.
_sub_storage
.
remove
.
apply
(
this
.
_sub_storage
,
param
=
JSON
.
stringify
(
param
);
arguments
);
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
()
{
CryptStorage
.
prototype
.
hasCapacity
=
function
()
{
var
async
=
{};
return
this
.
_sub_storage
.
hasCapacity
.
apply
(
this
.
_sub_storage
,
async
.
call
=
function
(
obj
,
function_name
,
arglist
)
{
arguments
);
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
;
};
};
that
.
post
=
function
(
command
)
{
CryptStorage
.
prototype
.
buildQuery
=
function
()
{
that
.
put
(
command
);
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
;
CryptStorage
.
prototype
.
putAttachment
=
function
(
id
,
name
,
blob
)
{
cloned_doc
.
content
=
new_file_content
;
var
iv
=
crypto
.
getRandomValues
(
new
Uint8Array
(
12
)),
that
.
addJob
(
'
put
'
,
priv
.
sub_storage_spec
,
cloned_doc
,
that
=
this
;
command
.
cloneOption
(),
success
,
error
);
};
am
.
wait
(
o
,
'
save
'
,
1
);
am
.
call
(
o
,
'
encryptFilePath
'
);
am
.
call
(
o
,
'
encryptFileContent
'
);
};
// end put
/**
return
new
RSVP
.
Queue
()
* Loads a document.
.
push
(
function
()
{
* @method get
return
jIO
.
util
.
readBlobAsDataURL
(
blob
);
*/
})
that
.
get
=
function
(
command
)
{
.
push
(
function
(
dataURL
)
{
var
new_file_name
,
am
=
priv
.
newAsyncModule
(),
//string->arraybuffer
o
=
{};
var
strLen
=
dataURL
.
currentTarget
.
result
.
length
,
o
.
encryptFilePath
=
function
()
{
buf
=
new
ArrayBuffer
(
strLen
),
priv
.
encrypt
(
command
.
getDocId
(),
function
(
res
)
{
bufView
=
new
Uint8Array
(
buf
),
new_file_name
=
res
;
i
;
am
.
call
(
o
,
'
get
'
);
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
/**
CryptStorage
.
prototype
.
getAttachment
=
function
(
id
,
name
)
{
* Gets a document list.
var
that
=
this
;
* @method allDocs
*/
return
that
.
_sub_storage
.
getAttachment
(
id
,
name
)
that
.
allDocs
=
function
(
command
)
{
.
push
(
function
(
blob
)
{
var
result_array
=
[],
if
(
blob
.
type
!==
MIME_TYPE
)
{
am
=
priv
.
newAsyncModule
(),
return
blob
;
o
=
{};
}
o
.
allDocs
=
function
()
{
return
new
RSVP
.
Queue
()
that
.
addJob
(
'
allDocs
'
,
priv
.
sub_storage_spec
,
null
,
.
push
(
function
()
{
command
.
cloneOption
(),
o
.
onSuccess
,
o
.
error
);
return
jIO
.
util
.
readBlobAsArrayBuffer
(
blob
);
};
})
o
.
onSuccess
=
function
(
val
)
{
.
push
(
function
(
coded
)
{
if
(
val
.
total_rows
===
0
)
{
var
iv
;
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
,
function
(
err
,
res
)
{
coded
=
coded
.
currentTarget
.
result
;
if
(
err
)
{
iv
=
new
Uint8Array
(
coded
.
slice
(
0
,
12
));
am
.
call
(
o
,
'
error
'
,
[
err
]);
return
crypto
.
subtle
.
decrypt
({
name
:
"
AES-GCM
"
,
iv
:
iv
},
}
else
{
that
.
_key
,
coded
.
slice
(
12
));
result_array
[
c
].
value
.
content
=
res
;
})
am
.
call
(
o
,
'
success
'
);
.
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
/**
CryptStorage
.
prototype
.
removeAttachment
=
function
()
{
* Removes a document.
return
this
.
_sub_storage
.
removeAttachment
.
apply
(
this
.
_sub_storage
,
* @method remove
arguments
);
*/
};
that
.
remove
=
function
(
command
)
{
var
new_file_name
,
o
=
{};
CryptStorage
.
prototype
.
allAttachments
=
function
()
{
o
.
encryptDocId
=
function
()
{
return
this
.
_sub_storage
.
allAttachments
.
apply
(
this
.
_sub_storage
,
priv
.
encrypt
(
command
.
getDocId
(),
function
(
res
)
{
arguments
);
new_file_name
=
res
;
};
o
.
removeDocument
();
});
jIO
.
addStorage
(
'
crypt
'
,
CryptStorage
);
};
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
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 @@
...
@@ -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