@@ -29,6 +29,70 @@ angular.module('openshiftConsole')
29
29
this . $get = function ( $location , $q , Logger ) {
30
30
var authLogger = Logger . get ( "auth" ) ;
31
31
32
+ var getRandomInts = function ( length ) {
33
+ var randomValues ;
34
+
35
+ if ( window . crypto && window . Uint32Array ) {
36
+ try {
37
+ var r = new Uint32Array ( length ) ;
38
+ window . crypto . getRandomValues ( r ) ;
39
+ randomValues = [ ] ;
40
+ for ( var j = 0 ; j < length ; j ++ ) {
41
+ randomValues . push ( r [ j ] ) ;
42
+ }
43
+ } catch ( e ) {
44
+ authLogger . debug ( "RedirectLoginService.getRandomInts: " , e ) ;
45
+ randomValues = null ;
46
+ }
47
+ }
48
+
49
+ if ( ! randomValues ) {
50
+ randomValues = [ ] ;
51
+ for ( var i = 0 ; i < length ; i ++ ) {
52
+ randomValues . push ( Math . floor ( Math . random ( ) * 4294967296 ) ) ;
53
+ }
54
+ }
55
+
56
+ return randomValues ;
57
+ } ;
58
+
59
+ var nonceKey = "RedirectLoginService.nonce" ;
60
+ var makeState = function ( then ) {
61
+ var nonce = String ( new Date ( ) . getTime ( ) ) + "-" + getRandomInts ( 8 ) . join ( "" ) ;
62
+ try {
63
+ window . localStorage [ nonceKey ] = nonce ;
64
+ } catch ( e ) {
65
+ authLogger . log ( "RedirectLoginService.makeState, localStorage error: " , e ) ;
66
+ }
67
+ return JSON . stringify ( { then : then , nonce :nonce } ) ;
68
+ } ;
69
+ var parseState = function ( state ) {
70
+ var retval = {
71
+ then : null ,
72
+ verified : false
73
+ } ;
74
+
75
+ var nonce = "" ;
76
+ try {
77
+ nonce = window . localStorage [ nonceKey ] ;
78
+ window . localStorage . removeItem ( nonceKey ) ;
79
+ } catch ( e ) {
80
+ authLogger . log ( "RedirectLoginService.parseState, localStorage error: " , e ) ;
81
+ }
82
+
83
+ try {
84
+ var data = state ? JSON . parse ( state ) : { } ;
85
+ if ( data && data . nonce && nonce && data . nonce === nonce ) {
86
+ retval . verified = true ;
87
+ retval . then = data . then ;
88
+ }
89
+ } catch ( e ) {
90
+ authLogger . error ( "RedirectLoginService.parseState, state error: " , e ) ;
91
+ }
92
+ authLogger . error ( "RedirectLoginService.parseState" , retval ) ;
93
+ return retval ;
94
+ } ;
95
+
32
96
return {
33
97
// Returns a promise that resolves with {user:{...}, token:'...', ttl:X }, or rejects with {error:'...'[,error_description:'...',error_uri:'...']}
34
98
login : function ( ) {
@@ -49,7 +113,7 @@ angular.module('openshiftConsole')
49
113
uri . query ( {
50
114
client_id : _oauth_client_id ,
51
115
response_type : 'token' ,
52
- state : returnUri . toString ( ) ,
116
+ state : makeState ( returnUri . toString ( ) ) ,
53
117
redirect_uri : _oauth_redirect_uri
54
118
} ) ;
55
119
authLogger . log ( "RedirectLoginService.login(), redirecting" , uri . toString ( ) ) ;
@@ -59,7 +123,7 @@ angular.module('openshiftConsole')
59
123
} ,
60
124
61
125
// Parses oauth callback parameters from window.location
62
- // Returns a promise that resolves with {token:'...',then:'...'}, or rejects with {error:'...'[,error_description:'...',error_uri:'...']}
126
+ // Returns a promise that resolves with {token:'...',then:'...',verified:true|false }, or rejects with {error:'...'[,error_description:'...',error_uri:'...']}
63
127
// If no token and no error is present, resolves with {}
64
128
// Example error codes: https://tools.ietf.org/html/rfc6749#section-5.2
65
129
finish : function ( ) {
@@ -71,12 +135,12 @@ angular.module('openshiftConsole')
71
135
var fragmentParams = new URI ( "?" + u . fragment ( ) ) . query ( true ) ;
72
136
authLogger . log ( "RedirectLoginService.finish()" , queryParams , fragmentParams ) ;
73
137
74
- // Error codes can come in query params or fragment params
75
- // Handle an error response from the OAuth server
138
+ // Error codes can come in query params or fragment params
139
+ // Handle an error response from the OAuth server
76
140
var error = queryParams . error || fragmentParams . error ;
77
- if ( error ) {
78
- var error_description = queryParams . error_description || fragmentParams . error_description ;
79
- var error_uri = queryParams . error_uri || fragmentParams . error_uri ;
141
+ if ( error ) {
142
+ var error_description = queryParams . error_description || fragmentParams . error_description ;
143
+ var error_uri = queryParams . error_uri || fragmentParams . error_uri ;
80
144
authLogger . log ( "RedirectLoginService.finish(), error" , error , error_description , error_uri ) ;
81
145
return $q . reject ( {
82
146
error : error ,
@@ -85,13 +149,16 @@ angular.module('openshiftConsole')
85
149
} ) ;
86
150
}
87
151
152
+ var stateData = parseState ( fragmentParams . state ) ;
153
+
88
154
// Handle an access_token response
89
155
if ( fragmentParams . access_token && ( fragmentParams . token_type || "" ) . toLowerCase ( ) === "bearer" ) {
90
156
var deferred = $q . defer ( ) ;
91
157
deferred . resolve ( {
92
158
token : fragmentParams . access_token ,
93
159
ttl : fragmentParams . expires_in ,
94
- then : fragmentParams . state
160
+ then : stateData . state ,
161
+ verified : stateData . verified
95
162
} ) ;
96
163
return deferred . promise ;
97
164
}
0 commit comments