WIP authorizationDecision
This commit is contained in:
		
							parent
							
								
									23ea5046bb
								
							
						
					
					
						commit
						9f923b5f65
					
				| @ -228,6 +228,201 @@ | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   , isIframe: function isIframe () { | ||||
|       try { | ||||
|         return window.self !== window.top; | ||||
|       } catch (e) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   , parseUrl: function (url) { | ||||
|       var parser = document.createElement('a'); | ||||
|       parser.href = url; | ||||
|       return parser; | ||||
|     } | ||||
|   , isRedirectHostSafe: function (referrerUrl, redirectUrl) { | ||||
|       var src = browser.parseUrl(referrerUrl); | ||||
|       var dst = browser.parseUrl(redirectUrl); | ||||
| 
 | ||||
|       // TODO how should we handle subdomains?
 | ||||
|       // It should be safe for api.example.com to redirect to example.com
 | ||||
|       // But it may not be safe for to example.com to redirect to aj.example.com
 | ||||
|       // It is also probably not safe for sally.example.com to redirect to john.example.com
 | ||||
|       // The client should have a list of allowed URLs to choose from and perhaps a wildcard will do
 | ||||
|       //
 | ||||
|       // api.example.com.evil.com SHOULD NOT match example.com
 | ||||
|       return dst.hostname !== src.hostname; | ||||
|     } | ||||
|   , checkRedirect: function (client, query) { | ||||
|       console.warn("[security] URL path checking not yet implemented"); | ||||
| 
 | ||||
|       var clientUrl = OAUTH3.core.normalizeUrl(client.url); | ||||
|       var redirectUrl = OAUTH3.core.normalizeUrl(query.redirect_uri); | ||||
| 
 | ||||
|       // General rule:
 | ||||
|       // I can callback to a shorter domain (fewer subs) or a shorter path (on the same domain)
 | ||||
|       // but not a longer (more subs) or different domain or a longer path (on the same domain)
 | ||||
| 
 | ||||
| 
 | ||||
|       // We can callback to an explicitly listed domain (TODO and path)
 | ||||
|       if (browser.isRedirectHostSafe(clientUrl, redirectUrl)) { | ||||
|         return true; | ||||
|       } | ||||
| 
 | ||||
|       return false; | ||||
|     } | ||||
|   /* | ||||
|   , redirect: function (redirect) { | ||||
|       if (parser.search) { | ||||
|         parser.search += '&'; | ||||
|       } else { | ||||
|         parser.search += '?'; | ||||
|       } | ||||
| 
 | ||||
|       parser.search += 'error=E_NO_SESSION'; | ||||
|       redirectUri = parser.href; | ||||
| 
 | ||||
|       window.location.href = redirectUri; | ||||
|     } | ||||
|   */ | ||||
| 
 | ||||
|   , hackFormSubmit: function (opts) { | ||||
|       opts = opts || {}; | ||||
|       scope.authorizationDecisionUri = DaplieApiConfig.providerUri + '/api/org.oauth3.provider/authorization_decision'; | ||||
|       scope.updateScope(); | ||||
| 
 | ||||
|       var redirectUri = scope.appQuery.redirect_uri.replace(/^https?:\/\//i, 'https://'); | ||||
|       var separator; | ||||
| 
 | ||||
|       // TODO check that we appropriately use '#' for implicit and '?' for code
 | ||||
|       // (server-side) in an OAuth2 backwards-compatible way
 | ||||
|       if ('token' === scope.appQuery.response_type) { | ||||
|         separator = '#'; | ||||
|       } | ||||
|       else if ('code' === scope.appQuery.response_type) { | ||||
|         separator = '?'; | ||||
|       } | ||||
|       else { | ||||
|         separator = '#'; | ||||
|       } | ||||
| 
 | ||||
|       if (scope.pendingScope.length && !opts.allow) { | ||||
|         redirectUri += separator + Oauth3.querystringify({ | ||||
|           error: 'access_denied' | ||||
|           , error_description: 'None of the permissions were accepted' | ||||
|           , error_uri: 'https://oauth3.org/docs/errors#access_denied' | ||||
|           , state: scope.appQuery.state | ||||
|         }); | ||||
|         $window.location.href = redirectUri; | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       // TODO move to Oauth3? or not?
 | ||||
|       // this could be implementation-specific,
 | ||||
|       // but it may still be nice to provide it as de-facto
 | ||||
|       var url = DaplieApiConfig.apiBaseUri + '/api/org.oauth3.provider/grants/:client_id/:account_id' | ||||
|         .replace(/:client_id/g, scope.appQuery.client_id || scope.appQuery.client_uri) | ||||
|         .replace(/:account_id/g, scope.selectedAccountId) | ||||
|         ; | ||||
| 
 | ||||
|       var account = scope.sessionAccount; | ||||
|       var session = { accessToken: account.token, refreshToken: account.refreshToken }; | ||||
|       var preq = { | ||||
|         url: url | ||||
|       , method: 'POST' | ||||
|       , data: { | ||||
|           scope: updateAccepted() | ||||
|         , response_type: scope.appQuery.response_type | ||||
|         , referrer: document.referrer || document.referer || '' | ||||
|         , referer: document.referrer || document.referer || '' | ||||
|         , tenant_id: scope.appQuery.tenant_id | ||||
|         , client_id: scope.appQuery.client_id | ||||
|         , client_uri: scope.appQuery.client_uri | ||||
|         } | ||||
|       , session: session | ||||
|       }; | ||||
|       preq.clientId = preq.appId = DaplieApiConfig.appId || DaplieApiConfig.clientId; | ||||
|       preq.clientUri = preq.appUri = DaplieApiConfig.appUri || DaplieApiConfig.clientUri; | ||||
|       console.log('hackFormSubmit preq', preq); | ||||
|       // TODO need a way to have middleware in Oauth3.request for TherapySession et al
 | ||||
|       return Oauth3.request(preq).then(function (resp) { | ||||
|         console.log('[DEBUG] grant code'); | ||||
|         console.log(resp); | ||||
| 
 | ||||
|         var err; | ||||
|         var data = resp.data || {}; | ||||
| 
 | ||||
|         if (data.error) { | ||||
|           err = new Error(data.error.message || data.errorDescription); | ||||
|           err.message = data.error.message || data.errorDescription; | ||||
|           err.code = resp.data.error.code || resp.data.error; | ||||
|           err.uri = 'https://oauth3.org/docs/errors#' + (resp.data.error.code || resp.data.error); | ||||
|           return $q.reject(err); | ||||
|         } | ||||
| 
 | ||||
|         if (!(data.code || data.accessToken)) { | ||||
|           err = new Error("No grant code"); | ||||
|           return $q.reject(err); | ||||
|         } | ||||
| 
 | ||||
|         return data; | ||||
|       }).then(function (data) { | ||||
|         redirectUri += separator + Oauth3.querystringify({ | ||||
|           state: scope.appQuery.state | ||||
| 
 | ||||
|         , code: data.code | ||||
| 
 | ||||
|         , access_token: data.accessToken | ||||
|         , expires_at: data.expiresAt | ||||
|         , expires_in: data.expiresIn | ||||
|         , scope: data.scope | ||||
| 
 | ||||
|         , refresh_token: data.refreshToken | ||||
|         , refresh_expires_at: data.refreshExpiresAt | ||||
|         , refresh_expires_in: data.refreshExpiresIn | ||||
|         }); | ||||
| 
 | ||||
|         if ('token' === scope.appQuery.response_type) { | ||||
|           $window.location.href = redirectUri; | ||||
|           return; | ||||
|         } | ||||
|         else if ('code' === scope.appQuery.response_type) { | ||||
|           scope.hackFormSubmitHelper(redirectUri); | ||||
|           return; | ||||
|         } | ||||
|         else { | ||||
|           console.warn("Grant Code NOT IMPLEMENTED for '" + scope.appQuery.response_type + "'"); | ||||
|           console.warn(redirectUri); | ||||
|           throw new Error("Grant Code NOT IMPLEMENTED for '" + scope.appQuery.response_type + "'"); | ||||
|         } | ||||
|       }, function (err) { | ||||
|         redirectUri += separator + Oauth3.querystringify({ | ||||
|           error: err.code || 'server_error' | ||||
|         , error_description: err.message || "Server Error: It's not your fault" | ||||
|         , error_uri: err.uri || 'https://oauth3.org/docs/errors#server_error' | ||||
|         , state: scope.appQuery.state | ||||
|         }); | ||||
| 
 | ||||
|         console.error('Grant Code Error NOT IMPLEMENTED'); | ||||
|         console.error(err); | ||||
|         console.error(redirectUri); | ||||
|         //$window.location.href = redirectUri;
 | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|   , hackFormSubmitHelper: function (uri) { | ||||
|       // TODO de-jQuerify
 | ||||
|       //$window.location.href = redirectUri;
 | ||||
|       //return;
 | ||||
| 
 | ||||
|       // the only way to do a POST that redirects the current window
 | ||||
|       window.jQuery('form.js-hack-hidden-form').attr('action', uri); | ||||
| 
 | ||||
|       // give time for the apply to take place
 | ||||
|       window.setTimeout(function () { | ||||
|         window.jQuery('form.js-hack-hidden-form').submit(); | ||||
|       }, 50); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   Object.keys(browser).forEach(function (key) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user