Repository: auth0/auth0-spa-js
Pull request #249 (2019-10-21 23:01:52)

Add a new property 'fragment' to be appended to the authorize URL on redirect
### Description

In some circumstances the URL may need to be mutated post-generation. An example use case is adding parameters to the hash (`#`) part of the URL in order to more safely transmit personally identifiable information.

I've added a new public method to return the URL instead of merely redirecting.

Potential use:
```
const url = await auth0.buildLoginUrl();
window.location.assign(`${url}#hint=user@auth0.com`);
```

### References

- Docs PR - auth0/docs#8405
- [Fragment Identifier](https://en.wikipedia.org/wiki/Fragment_identifier)
- [URL.hash](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash)

### Testing

Call the `buildLoginUrl` method available on `Auth0Client`. 
- [x] This change adds test coverage for new/changed/fixed functionality

### Checklist

- [x] I have added documentation for new/changed functionality in this PR or in auth0.com/docs
- [x] All active GitHub checks for tests, formatting, and security are passing
- [x] The correct base branch is being used, if not `master`


willhackett: @luisrudge if preferred, this is also an option:
https://github.com/auth0/auth0-spa-js/commit/88ac9573ecd04870b89572d35f1496deb0f3bc00
stevehobbsdev: Hey @willhackett, appreciate your patience with this. We'd like to go for option 2 (https://github.com/auth0/auth0-spa-js/commit/88ac9573ecd04870b89572d35f1496deb0f3bc00). Would you be able to rework the PR (or feel free to raise a new one) with that?

Thanks for the contribution!

Patch:
diff --git a/src/Auth0Client.ts b/src/Auth0Client.ts
index 7b2bb04..7a00589 100644
--- a/src/Auth0Client.ts
+++ b/src/Auth0Client.ts
@@ -218,6 +218,7 @@ export default class Auth0Client {
     const code_verifier = createRandomString();
     const code_challengeBuffer = await sha256(code_verifier);
     const code_challenge = bufferToBase64UrlEncoded(code_challengeBuffer);
+    const fragment = options.fragment ? `#${options.fragment}` : '';
     const params = this._getParams(
       authorizeOptions,
       stateIn,
@@ -233,7 +234,7 @@ export default class Auth0Client {
       scope: params.scope,
       audience: params.audience || 'default'
     });
-    window.location.assign(url);
+    window.location.assign(url + fragment);
   }
 
   /**
diff --git a/src/global.ts b/src/global.ts
index 4e4529f..8399438 100644
--- a/src/global.ts
+++ b/src/global.ts
@@ -118,6 +118,10 @@ interface RedirectLoginOptions extends BaseLoginOptions {
    * Used to store state before doing the redirect
    */
   appState?: any;
+  /**
+   * Used to add to the URL fragment before redirecting
+   */
+  fragment?: string;
 }
 
 interface RedirectLoginResult {


Test patch:
diff --git a/__tests__/index.test.ts b/__tests__/index.test.ts
index 89e654e..7ee7139 100644
--- a/__tests__/index.test.ts
+++ b/__tests__/index.test.ts
@@ -527,6 +527,17 @@ describe('Auth0', () => {
         `https://test.auth0.com/authorize?query=params${TEST_TELEMETRY_QUERY_STRING}`
       );
     });
+    it('calls `window.location.assign` with the correct url and fragment if provided', async () => {
+      const { auth0 } = await setup();
+
+      await auth0.loginWithRedirect({
+        ...REDIRECT_OPTIONS,
+        fragment: '/reset'
+      });
+      expect(window.location.assign).toHaveBeenCalledWith(
+        `https://test.auth0.com/authorize?query=params${TEST_TELEMETRY_QUERY_STRING}#/reset`
+      );
+    });
     it('can be called with no arguments', async () => {
       const { auth0 } = await setup();