Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
60189762
Commit
60189762
authored
Jan 19, 2015
by
Nick Stenning
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace Auth plugin with built version
parent
8f17874f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
233 additions
and
250 deletions
+233
-250
auth.coffee
h/static/scripts/annotator/plugin/auth.coffee
+0
-249
annotator.auth.js
h/static/scripts/vendor/annotator.auth.js
+232
-0
karma.config.js
karma.config.js
+1
-1
No files found.
h/static/scripts/annotator/plugin/auth.coffee
deleted
100644 → 0
View file @
8f17874f
# Public: Creates a Date object from an ISO8601 formatted date String.
#
# string - ISO8601 formatted date String.
#
# Returns Date instance.
createDateFromISO8601
=
(
string
)
->
regexp
=
"([0-9]{4})(-([0-9]{2})(-([0-9]{2})"
+
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(
\.
([0-9]+))?)?"
+
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"
d
=
string
.
match
(
new
RegExp
(
regexp
))
offset
=
0
date
=
new
Date
(
d
[
1
],
0
,
1
)
date
.
setMonth
(
d
[
3
]
-
1
)
if
d
[
3
]
date
.
setDate
(
d
[
5
])
if
d
[
5
]
date
.
setHours
(
d
[
7
])
if
d
[
7
]
date
.
setMinutes
(
d
[
8
])
if
d
[
8
]
date
.
setSeconds
(
d
[
10
])
if
d
[
10
]
date
.
setMilliseconds
(
Number
(
"0."
+
d
[
12
])
*
1000
)
if
d
[
12
]
if
d
[
14
]
offset
=
(
Number
(
d
[
16
])
*
60
)
+
Number
(
d
[
17
])
offset
*=
((
d
[
15
]
==
'-'
)
?
1
:
-
1
)
offset
-=
date
.
getTimezoneOffset
()
time
=
(
Number
(
date
)
+
(
offset
*
60
*
1000
))
date
.
setTime
(
Number
(
time
))
date
base64Decode
=
(
data
)
->
if
atob
?
# Gecko and Webkit provide native code for this
atob
(
data
)
else
# Adapted from MIT/BSD licensed code at http://phpjs.org/functions/base64_decode
# version 1109.2015
b64
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
i
=
0
ac
=
0
dec
=
""
tmp_arr
=
[]
if
not
data
return
data
data
+=
''
while
i
<
data
.
length
# unpack four hexets into three octets using index points in b64
h1
=
b64
.
indexOf
(
data
.
charAt
(
i
++
))
h2
=
b64
.
indexOf
(
data
.
charAt
(
i
++
))
h3
=
b64
.
indexOf
(
data
.
charAt
(
i
++
))
h4
=
b64
.
indexOf
(
data
.
charAt
(
i
++
))
bits
=
h1
<<
18
|
h2
<<
12
|
h3
<<
6
|
h4
o1
=
bits
>>
16
&
0xff
o2
=
bits
>>
8
&
0xff
o3
=
bits
&
0xff
if
h3
==
64
tmp_arr
[
ac
++
]
=
String
.
fromCharCode
(
o1
)
else
if
h4
==
64
tmp_arr
[
ac
++
]
=
String
.
fromCharCode
(
o1
,
o2
)
else
tmp_arr
[
ac
++
]
=
String
.
fromCharCode
(
o1
,
o2
,
o3
)
tmp_arr
.
join
(
''
)
base64UrlDecode
=
(
data
)
->
m
=
data
.
length
%
4
if
m
!=
0
for
i
in
[
0
...
4
-
m
]
data
+=
'='
data
=
data
.
replace
(
/-/g
,
'+'
)
data
=
data
.
replace
(
/_/g
,
'/'
)
base64Decode
(
data
)
parseToken
=
(
token
)
->
[
head
,
payload
,
sig
]
=
token
.
split
(
'.'
)
JSON
.
parse
(
base64UrlDecode
(
payload
))
# Public: Supports the Store plugin by providing Authentication headers.
class
Annotator
.
Plugin
.
Auth
extends
Annotator
.
Plugin
# User options that can be provided.
options
:
# An authentication token. Used to skip the request to the server for a
# a token.
token
:
null
# The URL on the local server to request an authentication token.
tokenUrl
:
'/auth/token'
# If true will try and fetch a token when the plugin is initialised.
autoFetch
:
true
# Public: Create a new instance of the Auth plugin.
#
# element - The element to bind all events to. Usually the Annotator#element.
# options - An Object literal containing user options.
#
# Examples
#
# plugin = new Annotator.Plugin.Auth(annotator.element, {
# tokenUrl: '/my/custom/path'
# })
#
# Returns instance of Auth.
constructor
:
(
element
,
options
)
->
super
# List of functions to be executed when we have a valid token.
@
waitingForToken
=
[]
if
@
options
.
token
this
.
setToken
(
@
options
.
token
)
else
this
.
requestToken
()
# Public: Makes a request to the local server for an authentication token.
#
# Examples
#
# auth.requestToken()
#
# Returns jqXHR object.
requestToken
:
->
@
requestInProgress
=
true
$
.
ajax
url
:
@
options
.
tokenUrl
dataType
:
'text'
xhrFields
:
withCredentials
:
true
# Send any auth cookies to the backend
# on success, set the auth token
.
done
(
data
,
status
,
xhr
)
=>
this
.
setToken
(
data
)
# on failure, relay any message given by the server to the user with a notification
.
fail
(
xhr
,
status
,
err
)
=>
msg
=
Annotator
.
_t
(
"Couldn't get auth token:"
)
console
.
error
"
#{
msg
}
#{
err
}
"
,
xhr
Annotator
.
showNotification
(
"
#{
msg
}
#{
xhr
.
responseText
}
"
,
Annotator
.
Notification
.
ERROR
)
# always reset the requestInProgress indicator
.
always
=>
@
requestInProgress
=
false
# Public: Sets the @token and checks it's validity. If the token is invalid
# requests a new one from the server.
#
# token - A token string.
#
# Examples
#
# auth.setToken('eyJh...9jQ3I')
#
# Returns nothing.
setToken
:
(
token
)
->
@
token
=
token
# Parse the token without verifying its authenticity:
@
_unsafeToken
=
parseToken
(
token
)
if
this
.
haveValidToken
()
if
@
options
.
autoFetch
# Set timeout to fetch new token 2 seconds before current token expiry
@
refreshTimeout
=
setTimeout
(()
=>
this
.
requestToken
()),
(
this
.
timeToExpiry
()
-
2
)
*
1000
# Set headers field on this.element
this
.
updateHeaders
()
# Run callbacks waiting for token
while
@
waitingForToken
.
length
>
0
@
waitingForToken
.
pop
()(
@
_unsafeToken
)
else
console
.
warn
Annotator
.
_t
(
"Didn't get a valid token."
)
if
@
options
.
autoFetch
console
.
warn
Annotator
.
_t
(
"Getting a new token in 10s."
)
setTimeout
(()
=>
this
.
requestToken
()),
10
*
1000
# Public: Checks the validity of the current token. Note that this *does
# not* check the authenticity of the token.
#
# Examples
#
# auth.haveValidToken() # => Returns true if valid.
#
# Returns true if the token is valid.
haveValidToken
:
()
->
allFields
=
@
_unsafeToken
&&
@
_unsafeToken
.
issuedAt
&&
@
_unsafeToken
.
ttl
&&
@
_unsafeToken
.
consumerKey
if
allFields
&&
this
.
timeToExpiry
()
>
0
return
true
else
return
false
# Public: Calculates the time in seconds until the current token expires.
#
# Returns Number of seconds until token expires.
timeToExpiry
:
->
now
=
new
Date
().
getTime
()
/
1000
issue
=
createDateFromISO8601
(
@
_unsafeToken
.
issuedAt
).
getTime
()
/
1000
expiry
=
issue
+
@
_unsafeToken
.
ttl
timeToExpiry
=
expiry
-
now
if
(
timeToExpiry
>
0
)
then
timeToExpiry
else
0
# Public: Updates the headers to be sent with the Store requests. This is
# achieved by updating the 'annotator:headers' key in the @element.data()
# store.
#
# Returns nothing.
updateHeaders
:
->
current
=
@
element
.
data
(
'annotator:headers'
)
@
element
.
data
(
'annotator:headers'
,
$
.
extend
(
current
,
{
'x-annotator-auth-token'
:
@
token
,
}))
# Runs the provided callback if a valid token is available. Otherwise requests
# a token until it recieves a valid one.
#
# callback - A callback function to call once a valid token is obtained.
#
# Examples
#
# auth.withToken ->
# store.loadAnnotations()
#
# Returns nothing.
withToken
:
(
callback
)
->
if
not
callback
?
return
if
this
.
haveValidToken
()
callback
(
@
_unsafeToken
)
else
this
.
waitingForToken
.
push
(
callback
)
if
not
@
requestInProgress
this
.
requestToken
()
h/static/scripts/vendor/annotator.auth.js
0 → 100644
View file @
60189762
/*
** Annotator v1.2.9-dev-b091a74
** https://github.com/okfn/annotator/
**
** Copyright 2015, the Annotator project contributors.
** Dual licensed under the MIT and GPLv3 licenses.
** https://github.com/okfn/annotator/blob/master/LICENSE
**
** Built at: 2015-01-19 11:35:26Z
*/
//
// Generated by CoffeeScript 1.6.3
(
function
()
{
var
base64Decode
,
base64UrlDecode
,
createDateFromISO8601
,
parseToken
,
__hasProp
=
{}.
hasOwnProperty
,
__extends
=
function
(
child
,
parent
)
{
for
(
var
key
in
parent
)
{
if
(
__hasProp
.
call
(
parent
,
key
))
child
[
key
]
=
parent
[
key
];
}
function
ctor
()
{
this
.
constructor
=
child
;
}
ctor
.
prototype
=
parent
.
prototype
;
child
.
prototype
=
new
ctor
();
child
.
__super__
=
parent
.
prototype
;
return
child
;
};
createDateFromISO8601
=
function
(
string
)
{
var
d
,
date
,
offset
,
regexp
,
time
,
_ref
;
regexp
=
"([0-9]{4})(-([0-9]{2})(-([0-9]{2})"
+
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(
\\
.([0-9]+))?)?"
+
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"
;
d
=
string
.
match
(
new
RegExp
(
regexp
));
offset
=
0
;
date
=
new
Date
(
d
[
1
],
0
,
1
);
if
(
d
[
3
])
{
date
.
setMonth
(
d
[
3
]
-
1
);
}
if
(
d
[
5
])
{
date
.
setDate
(
d
[
5
]);
}
if
(
d
[
7
])
{
date
.
setHours
(
d
[
7
]);
}
if
(
d
[
8
])
{
date
.
setMinutes
(
d
[
8
]);
}
if
(
d
[
10
])
{
date
.
setSeconds
(
d
[
10
]);
}
if
(
d
[
12
])
{
date
.
setMilliseconds
(
Number
(
"0."
+
d
[
12
])
*
1000
);
}
if
(
d
[
14
])
{
offset
=
(
Number
(
d
[
16
])
*
60
)
+
Number
(
d
[
17
]);
offset
*=
(
_ref
=
d
[
15
]
===
'-'
)
!=
null
?
_ref
:
{
1
:
-
1
};
}
offset
-=
date
.
getTimezoneOffset
();
time
=
Number
(
date
)
+
(
offset
*
60
*
1000
);
date
.
setTime
(
Number
(
time
));
return
date
;
};
base64Decode
=
function
(
data
)
{
var
ac
,
b64
,
bits
,
dec
,
h1
,
h2
,
h3
,
h4
,
i
,
o1
,
o2
,
o3
,
tmp_arr
;
if
(
typeof
atob
!==
"undefined"
&&
atob
!==
null
)
{
return
atob
(
data
);
}
else
{
b64
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
;
i
=
0
;
ac
=
0
;
dec
=
""
;
tmp_arr
=
[];
if
(
!
data
)
{
return
data
;
}
data
+=
''
;
while
(
i
<
data
.
length
)
{
h1
=
b64
.
indexOf
(
data
.
charAt
(
i
++
));
h2
=
b64
.
indexOf
(
data
.
charAt
(
i
++
));
h3
=
b64
.
indexOf
(
data
.
charAt
(
i
++
));
h4
=
b64
.
indexOf
(
data
.
charAt
(
i
++
));
bits
=
h1
<<
18
|
h2
<<
12
|
h3
<<
6
|
h4
;
o1
=
bits
>>
16
&
0xff
;
o2
=
bits
>>
8
&
0xff
;
o3
=
bits
&
0xff
;
if
(
h3
===
64
)
{
tmp_arr
[
ac
++
]
=
String
.
fromCharCode
(
o1
);
}
else
if
(
h4
===
64
)
{
tmp_arr
[
ac
++
]
=
String
.
fromCharCode
(
o1
,
o2
);
}
else
{
tmp_arr
[
ac
++
]
=
String
.
fromCharCode
(
o1
,
o2
,
o3
);
}
}
return
tmp_arr
.
join
(
''
);
}
};
base64UrlDecode
=
function
(
data
)
{
var
i
,
m
,
_i
,
_ref
;
m
=
data
.
length
%
4
;
if
(
m
!==
0
)
{
for
(
i
=
_i
=
0
,
_ref
=
4
-
m
;
0
<=
_ref
?
_i
<
_ref
:
_i
>
_ref
;
i
=
0
<=
_ref
?
++
_i
:
--
_i
)
{
data
+=
'='
;
}
}
data
=
data
.
replace
(
/-/g
,
'+'
);
data
=
data
.
replace
(
/_/g
,
'/'
);
return
base64Decode
(
data
);
};
parseToken
=
function
(
token
)
{
var
head
,
payload
,
sig
,
_ref
;
_ref
=
token
.
split
(
'.'
),
head
=
_ref
[
0
],
payload
=
_ref
[
1
],
sig
=
_ref
[
2
];
return
JSON
.
parse
(
base64UrlDecode
(
payload
));
};
Annotator
.
Plugin
.
Auth
=
(
function
(
_super
)
{
__extends
(
Auth
,
_super
);
Auth
.
prototype
.
options
=
{
token
:
null
,
tokenUrl
:
'/auth/token'
,
autoFetch
:
true
};
function
Auth
(
element
,
options
)
{
Auth
.
__super__
.
constructor
.
apply
(
this
,
arguments
);
this
.
waitingForToken
=
[];
if
(
this
.
options
.
token
)
{
this
.
setToken
(
this
.
options
.
token
);
}
else
{
this
.
requestToken
();
}
}
Auth
.
prototype
.
requestToken
=
function
()
{
var
_this
=
this
;
this
.
requestInProgress
=
true
;
return
$
.
ajax
({
url
:
this
.
options
.
tokenUrl
,
dataType
:
'text'
,
xhrFields
:
{
withCredentials
:
true
}
}).
done
(
function
(
data
,
status
,
xhr
)
{
return
_this
.
setToken
(
data
);
}).
fail
(
function
(
xhr
,
status
,
err
)
{
var
msg
;
msg
=
Annotator
.
_t
(
"Couldn't get auth token:"
);
console
.
error
(
""
+
msg
+
" "
+
err
,
xhr
);
return
Annotator
.
showNotification
(
""
+
msg
+
" "
+
xhr
.
responseText
,
Annotator
.
Notification
.
ERROR
);
}).
always
(
function
()
{
return
_this
.
requestInProgress
=
false
;
});
};
Auth
.
prototype
.
setToken
=
function
(
token
)
{
var
_results
,
_this
=
this
;
this
.
token
=
token
;
this
.
_unsafeToken
=
parseToken
(
token
);
if
(
this
.
haveValidToken
())
{
if
(
this
.
options
.
autoFetch
)
{
this
.
refreshTimeout
=
setTimeout
((
function
()
{
return
_this
.
requestToken
();
}),
(
this
.
timeToExpiry
()
-
2
)
*
1000
);
}
this
.
updateHeaders
();
_results
=
[];
while
(
this
.
waitingForToken
.
length
>
0
)
{
_results
.
push
(
this
.
waitingForToken
.
pop
()(
this
.
_unsafeToken
));
}
return
_results
;
}
else
{
console
.
warn
(
Annotator
.
_t
(
"Didn't get a valid token."
));
if
(
this
.
options
.
autoFetch
)
{
console
.
warn
(
Annotator
.
_t
(
"Getting a new token in 10s."
));
return
setTimeout
((
function
()
{
return
_this
.
requestToken
();
}),
10
*
1000
);
}
}
};
Auth
.
prototype
.
haveValidToken
=
function
()
{
var
allFields
;
allFields
=
this
.
_unsafeToken
&&
this
.
_unsafeToken
.
issuedAt
&&
this
.
_unsafeToken
.
ttl
&&
this
.
_unsafeToken
.
consumerKey
;
if
(
allFields
&&
this
.
timeToExpiry
()
>
0
)
{
return
true
;
}
else
{
return
false
;
}
};
Auth
.
prototype
.
timeToExpiry
=
function
()
{
var
expiry
,
issue
,
now
,
timeToExpiry
;
now
=
new
Date
().
getTime
()
/
1000
;
issue
=
createDateFromISO8601
(
this
.
_unsafeToken
.
issuedAt
).
getTime
()
/
1000
;
expiry
=
issue
+
this
.
_unsafeToken
.
ttl
;
timeToExpiry
=
expiry
-
now
;
if
(
timeToExpiry
>
0
)
{
return
timeToExpiry
;
}
else
{
return
0
;
}
};
Auth
.
prototype
.
updateHeaders
=
function
()
{
var
current
;
current
=
this
.
element
.
data
(
'annotator:headers'
);
return
this
.
element
.
data
(
'annotator:headers'
,
$
.
extend
(
current
,
{
'x-annotator-auth-token'
:
this
.
token
}));
};
Auth
.
prototype
.
withToken
=
function
(
callback
)
{
if
(
callback
==
null
)
{
return
;
}
if
(
this
.
haveValidToken
())
{
return
callback
(
this
.
_unsafeToken
);
}
else
{
this
.
waitingForToken
.
push
(
callback
);
if
(
!
this
.
requestInProgress
)
{
return
this
.
requestToken
();
}
}
};
return
Auth
;
})(
Annotator
.
Plugin
);
}).
call
(
this
);
//
//# sourceMappingURL=annotator.auth.map
\ No newline at end of file
karma.config.js
View file @
60189762
...
...
@@ -35,7 +35,7 @@ module.exports = function(config) {
'h/static/scripts/vendor/uuid.js'
,
'h/static/scripts/vendor/annotator.js'
,
'h/static/scripts/annotator/monkey.js'
,
'h/static/scripts/
annotator/plugin/
auth.js'
,
'h/static/scripts/
vendor/annotator.
auth.js'
,
'h/static/scripts/annotator/plugin/bridge.js'
,
'h/static/scripts/annotator/plugin/bucket-bar.js'
,
'h/static/scripts/annotator/plugin/threading.js'
,
...
...
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