Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
41b430b2
Commit
41b430b2
authored
Oct 09, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove u2f from globalnamespace
parent
d6170ce4
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
321 additions
and
374 deletions
+321
-374
app/assets/javascripts/dispatcher.js
app/assets/javascripts/dispatcher.js
+5
-2
app/assets/javascripts/main.js
app/assets/javascripts/main.js
+0
-6
app/assets/javascripts/two_factor_auth.js
app/assets/javascripts/two_factor_auth.js
+2
-1
app/assets/javascripts/u2f/authenticate.js
app/assets/javascripts/u2f/authenticate.js
+89
-99
app/assets/javascripts/u2f/error.js
app/assets/javascripts/u2f/error.js
+20
-23
app/assets/javascripts/u2f/register.js
app/assets/javascripts/u2f/register.js
+71
-80
app/assets/javascripts/u2f/util.js
app/assets/javascripts/u2f/util.js
+3
-12
spec/javascripts/u2f/authenticate_spec.js
spec/javascripts/u2f/authenticate_spec.js
+50
-59
spec/javascripts/u2f/mock_u2f_device.js
spec/javascripts/u2f/mock_u2f_device.js
+25
-28
spec/javascripts/u2f/register_spec.js
spec/javascripts/u2f/register_spec.js
+56
-64
No files found.
app/assets/javascripts/dispatcher.js
View file @
41b430b2
...
@@ -78,6 +78,7 @@ import initChangesDropdown from './init_changes_dropdown';
...
@@ -78,6 +78,7 @@ import initChangesDropdown from './init_changes_dropdown';
import
AbuseReports
from
'
./abuse_reports
'
;
import
AbuseReports
from
'
./abuse_reports
'
;
import
{
ajaxGet
,
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
import
{
ajaxGet
,
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
import
AjaxLoadingSpinner
from
'
./ajax_loading_spinner
'
;
import
AjaxLoadingSpinner
from
'
./ajax_loading_spinner
'
;
import
U2FAuthenticate
from
'
./u2f/authenticate
'
;
(
function
()
{
(
function
()
{
var
Dispatcher
;
var
Dispatcher
;
...
@@ -535,14 +536,16 @@ import AjaxLoadingSpinner from './ajax_loading_spinner';
...
@@ -535,14 +536,16 @@ import AjaxLoadingSpinner from './ajax_loading_spinner';
case
'
sessions
'
:
case
'
sessions
'
:
case
'
omniauth_callbacks
'
:
case
'
omniauth_callbacks
'
:
if
(
!
gon
.
u2f
)
break
;
if
(
!
gon
.
u2f
)
break
;
gl
.
u2fAuthenticate
=
new
gl
.
U2FAuthenticate
(
const
u2fAuthenticate
=
new
U2FAuthenticate
(
$
(
'
#js-authenticate-u2f
'
),
$
(
'
#js-authenticate-u2f
'
),
'
#js-login-u2f-form
'
,
'
#js-login-u2f-form
'
,
gon
.
u2f
,
gon
.
u2f
,
document
.
querySelector
(
'
#js-login-2fa-device
'
),
document
.
querySelector
(
'
#js-login-2fa-device
'
),
document
.
querySelector
(
'
.js-2fa-form
'
),
document
.
querySelector
(
'
.js-2fa-form
'
),
);
);
gl
.
u2fAuthenticate
.
start
();
u2fAuthenticate
.
start
();
// needed in rspec
gl
.
u2fAuthenticate
=
u2fAuthenticate
;
case
'
admin
'
:
case
'
admin
'
:
new
Admin
();
new
Admin
();
switch
(
path
[
1
])
{
switch
(
path
[
1
])
{
...
...
app/assets/javascripts/main.js
View file @
41b430b2
...
@@ -47,12 +47,6 @@ import './lib/utils/url_utility';
...
@@ -47,12 +47,6 @@ import './lib/utils/url_utility';
// behaviors
// behaviors
import
'
./behaviors/
'
;
import
'
./behaviors/
'
;
// u2f
import
'
./u2f/authenticate
'
;
import
'
./u2f/error
'
;
import
'
./u2f/register
'
;
import
'
./u2f/util
'
;
// everything else
// everything else
import
'
./activities
'
;
import
'
./activities
'
;
import
'
./admin
'
;
import
'
./admin
'
;
...
...
app/assets/javascripts/two_factor_auth.js
View file @
41b430b2
/* global U2FRegister */
import
U2FRegister
from
'
./u2f/register
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
twoFactorNode
=
document
.
querySelector
(
'
.js-two-factor-auth
'
);
const
twoFactorNode
=
document
.
querySelector
(
'
.js-two-factor-auth
'
);
const
skippable
=
twoFactorNode
.
dataset
.
twoFactorSkippable
===
'
true
'
;
const
skippable
=
twoFactorNode
.
dataset
.
twoFactorSkippable
===
'
true
'
;
...
...
app/assets/javascripts/u2f/authenticate.js
View file @
41b430b2
/* eslint-disable func-names,
space-before-function-paren, no-var, prefer-rest-params, wrap-iife, prefer-arrow-callback, no-else-return, quotes, quote-props, comma-dangle, one-var, one-var-declaration-per-line, max-len
*/
/* eslint-disable func-names,
wrap-iife
*/
/* global u2f */
/* global u2f */
/* global U2FError */
/* global U2FUtil */
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
isU2FSupported
from
'
./util
'
;
import
U2FError
from
'
./error
'
;
// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
//
//
// State Flow #1: setup -> in_progress -> authenticated -> POST to server
// State Flow #1: setup -> in_progress -> authenticated -> POST to server
// State Flow #2: setup -> in_progress -> error -> setup
// State Flow #2: setup -> in_progress -> error -> setup
(
function
()
{
export
default
class
U2FAuthenticate
{
const
global
=
window
.
gl
||
(
window
.
gl
=
{});
constructor
(
container
,
form
,
u2fParams
,
fallbackButton
,
fallbackUI
)
{
global
.
U2FAuthenticate
=
(
function
()
{
function
U2FAuthenticate
(
container
,
form
,
u2fParams
,
fallbackButton
,
fallbackUI
)
{
this
.
container
=
container
;
this
.
container
=
container
;
this
.
renderNotSupported
=
this
.
renderNotSupported
.
bind
(
this
);
this
.
renderNotSupported
=
this
.
renderNotSupported
.
bind
(
this
);
this
.
renderAuthenticated
=
this
.
renderAuthenticated
.
bind
(
this
);
this
.
renderAuthenticated
=
this
.
renderAuthenticated
.
bind
(
this
);
...
@@ -27,8 +23,10 @@ import _ from 'underscore';
...
@@ -27,8 +23,10 @@ import _ from 'underscore';
this
.
form
=
form
;
this
.
form
=
form
;
this
.
fallbackButton
=
fallbackButton
;
this
.
fallbackButton
=
fallbackButton
;
this
.
fallbackUI
=
fallbackUI
;
this
.
fallbackUI
=
fallbackUI
;
if
(
this
.
fallbackButton
)
this
.
fallbackButton
.
addEventListener
(
'
click
'
,
this
.
switchToFallbackUI
.
bind
(
this
));
if
(
this
.
fallbackButton
)
{
this
.
signRequests
=
u2fParams
.
sign_requests
.
map
(
function
(
request
)
{
this
.
fallbackButton
.
addEventListener
(
'
click
'
,
this
.
switchToFallbackUI
.
bind
(
this
));
}
// The U2F Javascript API v1.1 requires a single challenge, with
// The U2F Javascript API v1.1 requires a single challenge, with
// _no challenges per-request_. The U2F Javascript API v1.0 requires a
// _no challenges per-request_. The U2F Javascript API v1.0 requires a
// challenge per-request, which is done by copying the single challenge
// challenge per-request, which is done by copying the single challenge
...
@@ -40,79 +38,71 @@ import _ from 'underscore';
...
@@ -40,79 +38,71 @@ import _ from 'underscore';
// Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
// Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
// This can be removed once we upgrade.
// This can be removed once we upgrade.
// https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
// https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
return
_
(
request
).
omit
(
'
challenge
'
);
this
.
signRequests
=
u2fParams
.
sign_requests
.
map
(
request
=>
_
(
request
).
omit
(
'
challenge
'
));
});
this
.
templates
=
{
notSupported
:
'
#js-authenticate-u2f-not-supported
'
,
setup
:
'
#js-authenticate-u2f-setup
'
,
inProgress
:
'
#js-authenticate-u2f-in-progress
'
,
error
:
'
#js-authenticate-u2f-error
'
,
authenticated
:
'
#js-authenticate-u2f-authenticated
'
,
};
}
}
U2FAuthenticate
.
prototype
.
start
=
function
()
{
start
()
{
if
(
U2FUtil
.
isU2FSupported
())
{
if
(
isU2FSupported
())
{
return
this
.
renderInProgress
();
return
this
.
renderInProgress
();
}
else
{
}
return
this
.
renderNotSupported
();
return
this
.
renderNotSupported
();
}
}
};
U2FAuthenticate
.
prototype
.
authenticate
=
function
()
{
authenticate
()
{
return
u2f
.
sign
(
this
.
appId
,
this
.
challenge
,
this
.
signRequests
,
(
function
(
_this
)
{
return
u2f
.
sign
(
this
.
appId
,
this
.
challenge
,
this
.
signRequests
,
(
function
(
_this
)
{
return
function
(
response
)
{
return
function
(
response
)
{
var
error
;
if
(
response
.
errorCode
)
{
if
(
response
.
errorCode
)
{
error
=
new
U2FError
(
response
.
errorCode
,
'
authenticate
'
);
const
error
=
new
U2FError
(
response
.
errorCode
,
'
authenticate
'
);
return
_this
.
renderError
(
error
);
return
_this
.
renderError
(
error
);
}
else
{
return
_this
.
renderAuthenticated
(
JSON
.
stringify
(
response
));
}
}
return
_this
.
renderAuthenticated
(
JSON
.
stringify
(
response
));
};
};
})(
this
),
10
);
})(
this
),
10
);
};
}
// Rendering #
U2FAuthenticate
.
prototype
.
templates
=
{
"
notSupported
"
:
"
#js-authenticate-u2f-not-supported
"
,
"
setup
"
:
'
#js-authenticate-u2f-setup
'
,
"
inProgress
"
:
'
#js-authenticate-u2f-in-progress
'
,
"
error
"
:
'
#js-authenticate-u2f-error
'
,
"
authenticated
"
:
'
#js-authenticate-u2f-authenticated
'
};
U2FAuthenticate
.
prototype
.
renderTemplate
=
function
(
name
,
params
)
{
renderTemplate
(
name
,
params
)
{
var
template
,
templateString
;
const
templateString
=
$
(
this
.
templates
[
name
]).
html
();
templateString
=
$
(
this
.
templates
[
name
]).
html
();
const
template
=
_
.
template
(
templateString
);
template
=
_
.
template
(
templateString
);
return
this
.
container
.
html
(
template
(
params
));
return
this
.
container
.
html
(
template
(
params
));
};
}
U2FAuthenticate
.
prototype
.
renderInProgress
=
function
()
{
renderInProgress
()
{
this
.
renderTemplate
(
'
inProgress
'
);
this
.
renderTemplate
(
'
inProgress
'
);
return
this
.
authenticate
();
return
this
.
authenticate
();
};
}
U2FAuthenticate
.
prototype
.
renderError
=
function
(
error
)
{
renderError
(
error
)
{
this
.
renderTemplate
(
'
error
'
,
{
this
.
renderTemplate
(
'
error
'
,
{
error_message
:
error
.
message
(),
error_message
:
error
.
message
(),
error_code
:
error
.
errorCode
error_code
:
error
.
errorCode
,
});
});
return
this
.
container
.
find
(
'
#js-u2f-try-again
'
).
on
(
'
click
'
,
this
.
renderInProgress
);
return
this
.
container
.
find
(
'
#js-u2f-try-again
'
).
on
(
'
click
'
,
this
.
renderInProgress
);
};
}
U2FAuthenticate
.
prototype
.
renderAuthenticated
=
function
(
deviceResponse
)
{
renderAuthenticated
(
deviceResponse
)
{
this
.
renderTemplate
(
'
authenticated
'
);
this
.
renderTemplate
(
'
authenticated
'
);
const
container
=
this
.
container
[
0
];
const
container
=
this
.
container
[
0
];
container
.
querySelector
(
'
#js-device-response
'
).
value
=
deviceResponse
;
container
.
querySelector
(
'
#js-device-response
'
).
value
=
deviceResponse
;
container
.
querySelector
(
this
.
form
).
submit
();
container
.
querySelector
(
this
.
form
).
submit
();
this
.
fallbackButton
.
classList
.
add
(
'
hidden
'
);
this
.
fallbackButton
.
classList
.
add
(
'
hidden
'
);
};
}
U2FAuthenticate
.
prototype
.
renderNotSupported
=
function
()
{
renderNotSupported
()
{
return
this
.
renderTemplate
(
'
notSupported
'
);
return
this
.
renderTemplate
(
'
notSupported
'
);
};
}
U2FAuthenticate
.
prototype
.
switchToFallbackUI
=
function
()
{
switchToFallbackUI
()
{
this
.
fallbackButton
.
classList
.
add
(
'
hidden
'
);
this
.
fallbackButton
.
classList
.
add
(
'
hidden
'
);
this
.
container
[
0
].
classList
.
add
(
'
hidden
'
);
this
.
container
[
0
].
classList
.
add
(
'
hidden
'
);
this
.
fallbackUI
.
classList
.
remove
(
'
hidden
'
);
this
.
fallbackUI
.
classList
.
remove
(
'
hidden
'
);
};
}
return
U2FAuthenticate
;
}
})();
})();
app/assets/javascripts/u2f/error.js
View file @
41b430b2
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-console, quotes, prefer-template, max-len */
export
default
class
U2FError
{
/* global u2f */
constructor
(
errorCode
,
u2fFlowType
)
{
(
function
()
{
this
.
U2FError
=
(
function
()
{
function
U2FError
(
errorCode
,
u2fFlowType
)
{
this
.
errorCode
=
errorCode
;
this
.
errorCode
=
errorCode
;
this
.
message
=
this
.
message
.
bind
(
this
);
this
.
message
=
this
.
message
.
bind
(
this
);
this
.
httpsDisabled
=
window
.
location
.
protocol
!==
'
https:
'
;
this
.
httpsDisabled
=
window
.
location
.
protocol
!==
'
https:
'
;
this
.
u2fFlowType
=
u2fFlowType
;
this
.
u2fFlowType
=
u2fFlowType
;
}
}
U2FError
.
prototype
.
message
=
function
()
{
message
()
{
if
(
this
.
errorCode
===
u2f
.
ErrorCodes
.
BAD_REQUEST
&&
this
.
httpsDisabled
)
{
if
(
this
.
errorCode
===
window
.
u2f
.
ErrorCodes
.
BAD_REQUEST
&&
this
.
httpsDisabled
)
{
return
'
U2F only works with HTTPS-enabled websites. Contact your administrator for more details.
'
;
return
'
U2F only works with HTTPS-enabled websites. Contact your administrator for more details.
'
;
}
else
if
(
this
.
errorCode
===
u2f
.
ErrorCodes
.
DEVICE_INELIGIBLE
)
{
}
else
if
(
this
.
errorCode
===
window
.
u2f
.
ErrorCodes
.
DEVICE_INELIGIBLE
)
{
if
(
this
.
u2fFlowType
===
'
authenticate
'
)
return
'
This device has not been registered with us.
'
;
if
(
this
.
u2fFlowType
===
'
authenticate
'
)
{
if
(
this
.
u2fFlowType
===
'
register
'
)
return
'
This device has already
been registered with us.
'
;
return
'
This device has not
been registered with us.
'
;
}
}
return
"
There was a problem communicating with your device.
"
;
if
(
this
.
u2fFlowType
===
'
register
'
)
{
};
return
'
This device has already been registered with us.
'
;
}
return
U2FError
;
}
})();
return
'
There was a problem communicating with your device.
'
;
}).
call
(
window
);
}
}
app/assets/javascripts/u2f/register.js
View file @
41b430b2
/* eslint-disable func-names,
space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-else-return, quotes, quote-props, comma-dangle, one-var, one-var-declaration-per-line, max-len
*/
/* eslint-disable func-names,
wrap-iife
*/
/* global u2f */
/* global u2f */
/* global U2FError */
/* global U2FUtil */
import
_
from
'
underscore
'
;
import
_
from
'
underscore
'
;
import
isU2FSupported
from
'
./util
'
;
import
U2FError
from
'
./error
'
;
// Register U2F (universal 2nd factor) devices for users to authenticate with.
// Register U2F (universal 2nd factor) devices for users to authenticate with.
//
//
// State Flow #1: setup -> in_progress -> registered -> POST to server
// State Flow #1: setup -> in_progress -> registered -> POST to server
// State Flow #2: setup -> in_progress -> error -> setup
// State Flow #2: setup -> in_progress -> error -> setup
(
function
()
{
export
default
class
U2FRegister
{
this
.
U2FRegister
=
(
function
()
{
constructor
(
container
,
u2fParams
)
{
function
U2FRegister
(
container
,
u2fParams
)
{
this
.
container
=
container
;
this
.
container
=
container
;
this
.
renderNotSupported
=
this
.
renderNotSupported
.
bind
(
this
);
this
.
renderNotSupported
=
this
.
renderNotSupported
.
bind
(
this
);
this
.
renderRegistered
=
this
.
renderRegistered
.
bind
(
this
);
this
.
renderRegistered
=
this
.
renderRegistered
.
bind
(
this
);
...
@@ -24,75 +23,67 @@ import _ from 'underscore';
...
@@ -24,75 +23,67 @@ import _ from 'underscore';
this
.
appId
=
u2fParams
.
app_id
;
this
.
appId
=
u2fParams
.
app_id
;
this
.
registerRequests
=
u2fParams
.
register_requests
;
this
.
registerRequests
=
u2fParams
.
register_requests
;
this
.
signRequests
=
u2fParams
.
sign_requests
;
this
.
signRequests
=
u2fParams
.
sign_requests
;
this
.
templates
=
{
notSupported
:
'
#js-register-u2f-not-supported
'
,
setup
:
'
#js-register-u2f-setup
'
,
inProgress
:
'
#js-register-u2f-in-progress
'
,
error
:
'
#js-register-u2f-error
'
,
registered
:
'
#js-register-u2f-registered
'
,
};
}
}
U2FRegister
.
prototype
.
start
=
function
()
{
start
()
{
if
(
U2FUtil
.
isU2FSupported
())
{
if
(
isU2FSupported
())
{
return
this
.
renderSetup
();
return
this
.
renderSetup
();
}
else
{
}
return
this
.
renderNotSupported
();
return
this
.
renderNotSupported
();
}
}
};
U2FRegister
.
prototype
.
register
=
function
()
{
register
()
{
return
u2f
.
register
(
this
.
appId
,
this
.
registerRequests
,
this
.
signRequests
,
(
function
(
_this
)
{
return
u2f
.
register
(
this
.
appId
,
this
.
registerRequests
,
this
.
signRequests
,
(
function
(
_this
)
{
return
function
(
response
)
{
return
function
(
response
)
{
var
error
;
if
(
response
.
errorCode
)
{
if
(
response
.
errorCode
)
{
error
=
new
U2FError
(
response
.
errorCode
,
'
register
'
);
const
error
=
new
U2FError
(
response
.
errorCode
,
'
register
'
);
return
_this
.
renderError
(
error
);
return
_this
.
renderError
(
error
);
}
else
{
return
_this
.
renderRegistered
(
JSON
.
stringify
(
response
));
}
}
return
_this
.
renderRegistered
(
JSON
.
stringify
(
response
));
};
};
})(
this
),
10
);
})(
this
),
10
);
};
}
// Rendering #
U2FRegister
.
prototype
.
templates
=
{
"
notSupported
"
:
"
#js-register-u2f-not-supported
"
,
"
setup
"
:
'
#js-register-u2f-setup
'
,
"
inProgress
"
:
'
#js-register-u2f-in-progress
'
,
"
error
"
:
'
#js-register-u2f-error
'
,
"
registered
"
:
'
#js-register-u2f-registered
'
};
U2FRegister
.
prototype
.
renderTemplate
=
function
(
name
,
params
)
{
renderTemplate
(
name
,
params
)
{
var
template
,
templateString
;
const
templateString
=
$
(
this
.
templates
[
name
]).
html
();
templateString
=
$
(
this
.
templates
[
name
]).
html
();
const
template
=
_
.
template
(
templateString
);
template
=
_
.
template
(
templateString
);
return
this
.
container
.
html
(
template
(
params
));
return
this
.
container
.
html
(
template
(
params
));
};
}
U2FRegister
.
prototype
.
renderSetup
=
function
()
{
renderSetup
()
{
this
.
renderTemplate
(
'
setup
'
);
this
.
renderTemplate
(
'
setup
'
);
return
this
.
container
.
find
(
'
#js-setup-u2f-device
'
).
on
(
'
click
'
,
this
.
renderInProgress
);
return
this
.
container
.
find
(
'
#js-setup-u2f-device
'
).
on
(
'
click
'
,
this
.
renderInProgress
);
};
}
U2FRegister
.
prototype
.
renderInProgress
=
function
()
{
renderInProgress
()
{
this
.
renderTemplate
(
'
inProgress
'
);
this
.
renderTemplate
(
'
inProgress
'
);
return
this
.
register
();
return
this
.
register
();
};
}
U2FRegister
.
prototype
.
renderError
=
function
(
error
)
{
renderError
(
error
)
{
this
.
renderTemplate
(
'
error
'
,
{
this
.
renderTemplate
(
'
error
'
,
{
error_message
:
error
.
message
(),
error_message
:
error
.
message
(),
error_code
:
error
.
errorCode
error_code
:
error
.
errorCode
,
});
});
return
this
.
container
.
find
(
'
#js-u2f-try-again
'
).
on
(
'
click
'
,
this
.
renderSetup
);
return
this
.
container
.
find
(
'
#js-u2f-try-again
'
).
on
(
'
click
'
,
this
.
renderSetup
);
};
}
U2FRegister
.
prototype
.
renderRegistered
=
function
(
deviceResponse
)
{
renderRegistered
(
deviceResponse
)
{
this
.
renderTemplate
(
'
registered
'
);
this
.
renderTemplate
(
'
registered
'
);
// Prefer to do this instead of interpolating using Underscore templates
// Prefer to do this instead of interpolating using Underscore templates
// because of JSON escaping issues.
// because of JSON escaping issues.
return
this
.
container
.
find
(
"
#js-device-response
"
).
val
(
deviceResponse
);
return
this
.
container
.
find
(
'
#js-device-response
'
).
val
(
deviceResponse
);
};
}
U2FRegister
.
prototype
.
renderNotSupported
=
function
()
{
renderNotSupported
()
{
return
this
.
renderTemplate
(
'
notSupported
'
);
return
this
.
renderTemplate
(
'
notSupported
'
);
};
}
}
return
U2FRegister
;
})();
}).
call
(
window
);
app/assets/javascripts/u2f/util.js
View file @
41b430b2
/* eslint-disable func-names, space-before-function-paren, wrap-iife */
export
default
function
isU2FSupported
()
{
(
function
()
{
this
.
U2FUtil
=
(
function
()
{
function
U2FUtil
()
{}
U2FUtil
.
isU2FSupported
=
function
()
{
return
window
.
u2f
;
return
window
.
u2f
;
};
}
return
U2FUtil
;
})();
}).
call
(
window
);
spec/javascripts/u2f/authenticate_spec.js
View file @
41b430b2
/* eslint-disable space-before-function-paren, new-parens, quotes, comma-dangle, no-var, one-var, one-var-declaration-per-line, max-len */
import
U2FAuthenticate
from
'
~/u2f/authenticate
'
;
/* global MockU2FDevice */
/* global U2FAuthenticate */
import
'
~/u2f/authenticate
'
;
import
'
~/u2f/util
'
;
import
'
~/u2f/error
'
;
import
'
vendor/u2f
'
;
import
'
vendor/u2f
'
;
import
'
./mock_u2f_device
'
;
import
MockU2FDevice
from
'
./mock_u2f_device
'
;
(
function
()
{
describe
(
'
U2FAuthenticate
'
,
()
=>
{
describe
(
'
U2FAuthenticate
'
,
function
()
{
preloadFixtures
(
'
u2f/authenticate.html.raw
'
);
preloadFixtures
(
'
u2f/authenticate.html.raw
'
);
beforeEach
(
function
()
{
beforeEach
(()
=>
{
loadFixtures
(
'
u2f/authenticate.html.raw
'
);
loadFixtures
(
'
u2f/authenticate.html.raw
'
);
this
.
u2fDevice
=
new
MockU2FDevice
;
this
.
u2fDevice
=
new
MockU2FDevice
()
;
this
.
container
=
$
(
"
#js-authenticate-u2f
"
);
this
.
container
=
$
(
'
#js-authenticate-u2f
'
);
this
.
component
=
new
window
.
gl
.
U2FAuthenticate
(
this
.
component
=
new
U2FAuthenticate
(
this
.
container
,
this
.
container
,
'
#js-login-u2f-form
'
,
'
#js-login-u2f-form
'
,
{
{
sign_requests
:
[]
sign_requests
:
[],
},
},
document
.
querySelector
(
'
#js-login-2fa-device
'
),
document
.
querySelector
(
'
#js-login-2fa-device
'
),
document
.
querySelector
(
'
.js-2fa-form
'
)
document
.
querySelector
(
'
.js-2fa-form
'
),
);
);
// bypass automatic form submission within renderAuthenticated
// bypass automatic form submission within renderAuthenticated
...
@@ -31,42 +24,40 @@ import './mock_u2f_device';
...
@@ -31,42 +24,40 @@ import './mock_u2f_device';
return
this
.
component
.
start
();
return
this
.
component
.
start
();
});
});
it
(
'
allows authenticating via a U2F device
'
,
function
()
{
var
inProgressMessage
;
it
(
'
allows authenticating via a U2F device
'
,
()
=>
{
inProgressMessage
=
this
.
container
.
find
(
"
p
"
);
const
inProgressMessage
=
this
.
container
.
find
(
'
p
'
);
expect
(
inProgressMessage
.
text
()).
toContain
(
"
Trying to communicate with your device
"
);
expect
(
inProgressMessage
.
text
()).
toContain
(
'
Trying to communicate with your device
'
);
this
.
u2fDevice
.
respondToAuthenticateRequest
({
this
.
u2fDevice
.
respondToAuthenticateRequest
({
deviceData
:
"
this is data from the device
"
deviceData
:
'
this is data from the device
'
,
});
});
expect
(
this
.
component
.
renderAuthenticated
).
toHaveBeenCalledWith
(
'
{"deviceData":"this is data from the device"}
'
);
expect
(
this
.
component
.
renderAuthenticated
).
toHaveBeenCalledWith
(
'
{"deviceData":"this is data from the device"}
'
);
});
});
return
describe
(
"
errors
"
,
function
()
{
it
(
"
displays an error message
"
,
function
()
{
return
describe
(
'
errors
'
,
()
=>
{
var
errorMessage
,
setupButton
;
it
(
'
displays an error message
'
,
()
=>
{
setupButton
=
this
.
container
.
find
(
"
#js-login-u2f-device
"
);
const
setupButton
=
this
.
container
.
find
(
'
#js-login-u2f-device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToAuthenticateRequest
({
this
.
u2fDevice
.
respondToAuthenticateRequest
({
errorCode
:
"
error!
"
errorCode
:
'
error!
'
,
});
});
errorMessage
=
this
.
container
.
find
(
"
p
"
);
const
errorMessage
=
this
.
container
.
find
(
'
p
'
);
return
expect
(
errorMessage
.
text
()).
toContain
(
"
There was a problem communicating with your device
"
);
return
expect
(
errorMessage
.
text
()).
toContain
(
'
There was a problem communicating with your device
'
);
});
});
return
it
(
"
allows retrying authentication after an error
"
,
function
()
{
return
it
(
'
allows retrying authentication after an error
'
,
()
=>
{
var
retryButton
,
setupButton
;
let
setupButton
=
this
.
container
.
find
(
'
#js-login-u2f-device
'
);
setupButton
=
this
.
container
.
find
(
"
#js-login-u2f-device
"
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToAuthenticateRequest
({
this
.
u2fDevice
.
respondToAuthenticateRequest
({
errorCode
:
"
error!
"
errorCode
:
'
error!
'
,
});
});
retryButton
=
this
.
container
.
find
(
"
#js-u2f-try-again
"
);
const
retryButton
=
this
.
container
.
find
(
'
#js-u2f-try-again
'
);
retryButton
.
trigger
(
'
click
'
);
retryButton
.
trigger
(
'
click
'
);
setupButton
=
this
.
container
.
find
(
"
#js-login-u2f-device
"
);
setupButton
=
this
.
container
.
find
(
'
#js-login-u2f-device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToAuthenticateRequest
({
this
.
u2fDevice
.
respondToAuthenticateRequest
({
deviceData
:
"
this is data from the device
"
deviceData
:
'
this is data from the device
'
,
});
});
expect
(
this
.
component
.
renderAuthenticated
).
toHaveBeenCalledWith
(
'
{"deviceData":"this is data from the device"}
'
);
expect
(
this
.
component
.
renderAuthenticated
).
toHaveBeenCalledWith
(
'
{"deviceData":"this is data from the device"}
'
);
});
});
});
});
});
});
}).
call
(
window
);
spec/javascripts/u2f/mock_u2f_device.js
View file @
41b430b2
/* eslint-disable space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-expressions, no-return-assign, no-param-reassign, max-len */
/* eslint-disable prefer-rest-params, wrap-iife,
no-unused-expressions, no-return-assign, no-param-reassign*/
(
function
()
{
export
default
class
MockU2FDevice
{
this
.
MockU2FDevice
=
(
function
()
{
constructor
()
{
function
MockU2FDevice
()
{
this
.
respondToAuthenticateRequest
=
this
.
respondToAuthenticateRequest
.
bind
(
this
);
this
.
respondToAuthenticateRequest
=
this
.
respondToAuthenticateRequest
.
bind
(
this
);
this
.
respondToRegisterRequest
=
this
.
respondToRegisterRequest
.
bind
(
this
);
this
.
respondToRegisterRequest
=
this
.
respondToRegisterRequest
.
bind
(
this
);
window
.
u2f
||
(
window
.
u2f
=
{});
window
.
u2f
||
(
window
.
u2f
=
{});
window
.
u2f
.
register
=
(
function
(
_this
)
{
window
.
u2f
.
register
=
(
function
(
_this
)
{
return
function
(
appId
,
registerRequests
,
signRequests
,
callback
)
{
return
function
(
appId
,
registerRequests
,
signRequests
,
callback
)
{
return
_this
.
registerCallback
=
callback
;
return
_this
.
registerCallback
=
callback
;
};
};
})(
this
);
})(
this
);
window
.
u2f
.
sign
=
(
function
(
_this
)
{
window
.
u2f
.
sign
=
(
function
(
_this
)
{
return
function
(
appId
,
challenges
,
signRequests
,
callback
)
{
return
function
(
appId
,
challenges
,
signRequests
,
callback
)
{
return
_this
.
authenticateCallback
=
callback
;
return
_this
.
authenticateCallback
=
callback
;
};
};
})(
this
);
})(
this
);
}
}
MockU2FDevice
.
prototype
.
respondToRegisterRequest
=
function
(
params
)
{
respondToRegisterRequest
(
params
)
{
return
this
.
registerCallback
(
params
);
return
this
.
registerCallback
(
params
);
};
}
MockU2FDevice
.
prototype
.
respondToAuthenticateRequest
=
function
(
params
)
{
respondToAuthenticateRequest
(
params
)
{
return
this
.
authenticateCallback
(
params
);
return
this
.
authenticateCallback
(
params
);
};
}
}
return
MockU2FDevice
;
})();
}).
call
(
window
);
spec/javascripts/u2f/register_spec.js
View file @
41b430b2
/* eslint-disable space-before-function-paren, new-parens, quotes, no-var, one-var, one-var-declaration-per-line, comma-dangle, max-len */
import
U2FRegister
from
'
~/u2f/register
'
;
/* global MockU2FDevice */
/* global U2FRegister */
import
'
~/u2f/register
'
;
import
'
~/u2f/util
'
;
import
'
~/u2f/error
'
;
import
'
vendor/u2f
'
;
import
'
vendor/u2f
'
;
import
'
./mock_u2f_device
'
;
import
MockU2FDevice
from
'
./mock_u2f_device
'
;
(
function
()
{
describe
(
'
U2FRegister
'
,
()
=>
{
describe
(
'
U2FRegister
'
,
function
()
{
preloadFixtures
(
'
u2f/register.html.raw
'
);
preloadFixtures
(
'
u2f/register.html.raw
'
);
beforeEach
(
function
()
{
beforeEach
(()
=>
{
loadFixtures
(
'
u2f/register.html.raw
'
);
loadFixtures
(
'
u2f/register.html.raw
'
);
this
.
u2fDevice
=
new
MockU2FDevice
;
this
.
u2fDevice
=
new
MockU2FDevice
()
;
this
.
container
=
$
(
"
#js-register-u2f
"
);
this
.
container
=
$
(
'
#js-register-u2f
'
);
this
.
component
=
new
U2FRegister
(
this
.
container
,
$
(
"
#js-register-u2f-templates
"
),
{},
"
token
"
);
this
.
component
=
new
U2FRegister
(
this
.
container
,
$
(
'
#js-register-u2f-templates
'
),
{},
'
token
'
);
return
this
.
component
.
start
();
return
this
.
component
.
start
();
});
});
it
(
'
allows registering a U2F device
'
,
function
()
{
var
deviceResponse
,
inProgressMessage
,
registeredMessage
,
setupButton
;
it
(
'
allows registering a U2F device
'
,
()
=>
{
setupButton
=
this
.
container
.
find
(
"
#js-setup-u2f-device
"
);
const
setupButton
=
this
.
container
.
find
(
'
#js-setup-u2f-device
'
);
expect
(
setupButton
.
text
()).
toBe
(
'
Setup new U2F device
'
);
expect
(
setupButton
.
text
()).
toBe
(
'
Setup new U2F device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
inProgressMessage
=
this
.
container
.
children
(
"
p
"
);
const
inProgressMessage
=
this
.
container
.
children
(
'
p
'
);
expect
(
inProgressMessage
.
text
()).
toContain
(
"
Trying to communicate with your device
"
);
expect
(
inProgressMessage
.
text
()).
toContain
(
'
Trying to communicate with your device
'
);
this
.
u2fDevice
.
respondToRegisterRequest
({
this
.
u2fDevice
.
respondToRegisterRequest
({
deviceData
:
"
this is data from the device
"
deviceData
:
'
this is data from the device
'
,
});
});
registeredMessage
=
this
.
container
.
find
(
'
p
'
);
const
registeredMessage
=
this
.
container
.
find
(
'
p
'
);
deviceResponse
=
this
.
container
.
find
(
'
#js-device-response
'
);
const
deviceResponse
=
this
.
container
.
find
(
'
#js-device-response
'
);
expect
(
registeredMessage
.
text
()).
toContain
(
"
Your device was successfully set up!
"
);
expect
(
registeredMessage
.
text
()).
toContain
(
'
Your device was successfully set up!
'
);
return
expect
(
deviceResponse
.
val
()).
toBe
(
'
{"deviceData":"this is data from the device"}
'
);
return
expect
(
deviceResponse
.
val
()).
toBe
(
'
{"deviceData":"this is data from the device"}
'
);
});
});
return
describe
(
"
errors
"
,
function
()
{
it
(
"
doesn't allow the same device to be registered twice (for the same user
"
,
function
()
{
return
describe
(
'
errors
'
,
()
=>
{
var
errorMessage
,
setupButton
;
it
(
'
doesn
\'
t allow the same device to be registered twice (for the same user
'
,
()
=>
{
setupButton
=
this
.
container
.
find
(
"
#js-setup-u2f-device
"
);
const
setupButton
=
this
.
container
.
find
(
'
#js-setup-u2f-device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToRegisterRequest
({
this
.
u2fDevice
.
respondToRegisterRequest
({
errorCode
:
4
errorCode
:
4
,
});
});
errorMessage
=
this
.
container
.
find
(
"
p
"
);
const
errorMessage
=
this
.
container
.
find
(
'
p
'
);
return
expect
(
errorMessage
.
text
()).
toContain
(
"
already been registered with us
"
);
return
expect
(
errorMessage
.
text
()).
toContain
(
'
already been registered with us
'
);
});
});
it
(
"
displays an error message for other errors
"
,
function
()
{
var
errorMessage
,
setupButton
;
it
(
'
displays an error message for other errors
'
,
()
=>
{
setupButton
=
this
.
container
.
find
(
"
#js-setup-u2f-device
"
);
const
setupButton
=
this
.
container
.
find
(
'
#js-setup-u2f-device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToRegisterRequest
({
this
.
u2fDevice
.
respondToRegisterRequest
({
errorCode
:
"
error!
"
errorCode
:
'
error!
'
,
});
});
errorMessage
=
this
.
container
.
find
(
"
p
"
);
const
errorMessage
=
this
.
container
.
find
(
'
p
'
);
return
expect
(
errorMessage
.
text
()).
toContain
(
"
There was a problem communicating with your device
"
);
return
expect
(
errorMessage
.
text
()).
toContain
(
'
There was a problem communicating with your device
'
);
});
});
return
it
(
"
allows retrying registration after an error
"
,
function
()
{
var
registeredMessage
,
retryButton
,
setupButton
;
return
it
(
'
allows retrying registration after an error
'
,
()
=>
{
setupButton
=
this
.
container
.
find
(
"
#js-setup-u2f-device
"
);
let
setupButton
=
this
.
container
.
find
(
'
#js-setup-u2f-device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToRegisterRequest
({
this
.
u2fDevice
.
respondToRegisterRequest
({
errorCode
:
"
error!
"
errorCode
:
'
error!
'
,
});
});
retryButton
=
this
.
container
.
find
(
"
#U2FTryAgain
"
);
const
retryButton
=
this
.
container
.
find
(
'
#U2FTryAgain
'
);
retryButton
.
trigger
(
'
click
'
);
retryButton
.
trigger
(
'
click
'
);
setupButton
=
this
.
container
.
find
(
"
#js-setup-u2f-device
"
);
setupButton
=
this
.
container
.
find
(
'
#js-setup-u2f-device
'
);
setupButton
.
trigger
(
'
click
'
);
setupButton
.
trigger
(
'
click
'
);
this
.
u2fDevice
.
respondToRegisterRequest
({
this
.
u2fDevice
.
respondToRegisterRequest
({
deviceData
:
"
this is data from the device
"
deviceData
:
'
this is data from the device
'
,
});
registeredMessage
=
this
.
container
.
find
(
"
p
"
);
return
expect
(
registeredMessage
.
text
()).
toContain
(
"
Your device was successfully set up!
"
);
});
});
const
registeredMessage
=
this
.
container
.
find
(
'
p
'
);
return
expect
(
registeredMessage
.
text
()).
toContain
(
'
Your device was successfully set up!
'
);
});
});
});
});
})
.
call
(
window
)
;
});
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