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
Stefane Fermigier
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
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