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) {
 | 
					  Object.keys(browser).forEach(function (key) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user