auth-utils.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. /**
  2. * Utilities for handling OAuth resource URIs.
  3. */
  4. /**
  5. * Converts a server URL to a resource URL by removing the fragment.
  6. * RFC 8707 section 2 states that resource URIs "MUST NOT include a fragment component".
  7. * Keeps everything else unchanged (scheme, domain, port, path, query).
  8. */
  9. export function resourceUrlFromServerUrl(url) {
  10. const resourceURL = typeof url === 'string' ? new URL(url) : new URL(url.href);
  11. resourceURL.hash = ''; // Remove fragment
  12. return resourceURL;
  13. }
  14. /**
  15. * Checks if a requested resource URL matches a configured resource URL.
  16. * A requested resource matches if it has the same scheme, domain, port,
  17. * and its path starts with the configured resource's path.
  18. *
  19. * @param requestedResource The resource URL being requested
  20. * @param configuredResource The resource URL that has been configured
  21. * @returns true if the requested resource matches the configured resource, false otherwise
  22. */
  23. export function checkResourceAllowed({ requestedResource, configuredResource }) {
  24. const requested = typeof requestedResource === 'string' ? new URL(requestedResource) : new URL(requestedResource.href);
  25. const configured = typeof configuredResource === 'string' ? new URL(configuredResource) : new URL(configuredResource.href);
  26. // Compare the origin (scheme, domain, and port)
  27. if (requested.origin !== configured.origin) {
  28. return false;
  29. }
  30. // Handle cases like requested=/foo and configured=/foo/
  31. if (requested.pathname.length < configured.pathname.length) {
  32. return false;
  33. }
  34. // Check if the requested path starts with the configured path
  35. // Ensure both paths end with / for proper comparison
  36. // This ensures that if we have paths like "/api" and "/api/users",
  37. // we properly detect that "/api/users" is a subpath of "/api"
  38. // By adding a trailing slash if missing, we avoid false positives
  39. // where paths like "/api123" would incorrectly match "/api"
  40. const requestedPath = requested.pathname.endsWith('/') ? requested.pathname : requested.pathname + '/';
  41. const configuredPath = configured.pathname.endsWith('/') ? configured.pathname : configured.pathname + '/';
  42. return requestedPath.startsWith(configuredPath);
  43. }
  44. //# sourceMappingURL=auth-utils.js.map