-
Notifications
You must be signed in to change notification settings - Fork 3
Iframe manager #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Iframe manager #253
Conversation
🦋 Changeset detectedLatest commit: 04b506c The changes in this PR will be included in the next version bump. This PR includes changesets to release 8 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
View your CI Pipeline Execution ↗ for commit 04b506c.
☁️ Nx Cloud last updated this comment at |
|
Deployed 800732c to https://ForgeRock.github.io/ping-javascript-sdk/pr-253/800732cf7d06bf3fa9e29cc7ffbf5d1b63df3c25 branch gh-pages in ForgeRock/ping-javascript-sdk |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #253 +/- ##
==========================================
- Coverage 49.45% 49.33% -0.13%
==========================================
Files 29 29
Lines 1567 1571 +4
Branches 172 173 +1
==========================================
Hits 775 775
- Misses 792 796 +4 🚀 New features to boost your workflow:
|
| @@ -1,10 +1,3 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have to put this back
cerebrl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preliminary review.
| if ( | ||
| newHref === 'about:blank' || | ||
| !newHref.startsWith(options.url.substring(0, options.url.indexOf('?'))) | ||
| ) { | ||
| // Check if the newHref origin matches expected redirect_uri origin if possible | ||
| // Or simply check if it contains expected parameters. | ||
| // For now, we proceed assuming any load could be the redirect. | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this if we don't do anything with the condition?
| * @param options - The options for the iframe request (URL, timeout). | ||
| * @returns A Promise that resolves with the query parameters from the redirect URL or rejects on timeout or error. | ||
| */ | ||
| const getAuthCodeByIFrame = (options: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to make this more generic? In other words, could this just be getValuesByIframe? So, this just creates an iframe in a generic way, and detects for the values that are given as arguments. That way, this function doesn't have to know what values to look for or what's relevant. It just manages the iframe, the event listeners, the cleanup, etc. So, it could be useful for getting a Authorization Code or anything else. I'd say, it needs success values and error values to listen for.
7bba5de to
7aaad9d
Compare
| */ | ||
| export type ResponseType = 'code' | 'token'; | ||
|
|
||
| export interface GetAuthorizationUrlOptions extends LegacyConfigOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are authorize types in the utilities package? They don't seem to be used here. Did you mean to place them in the sdk-types or effects package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are used below, I can move it to the types package though, I don't have a strong opinion, but we should probably try to create some concrete rules as to when a type goes to types versus living with other types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point out where below? I'm not seeing these types used in utilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just meant it's used in this file, but yeah we can move it thats fine by me
| * @returns A Promise that resolves with the query parameters from the redirect URL or rejects on timeout or error. | ||
| */ | ||
| const getAuthCodeByIFrame = (options: { | ||
| url: AuthorizeUrl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering why we opted for a url param here instead of creating an authorize url based off some options passed in like the legacy sdk does? With the url param I would think a disadvantage for the end user is knowing how to construct a well formed authorize url.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Justin wanted us to pass in the authorize url here rather than create it in this function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is in an effort to generalize this iframe function and "flatten" what these functions do for better composability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make sure to remove the AuthorizeUrl type dependency here.
7aaad9d to
ccdaff9
Compare
c2a5f62 to
b398fa8
Compare
| */ | ||
|
|
||
| /* eslint-disable @typescript-eslint/no-empty-function */ | ||
| import { AuthorizeUrl } from '@forgerock/sdk-types'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this no longer has any "Authorize" related functions, we should remove the need for this type.
| * | ||
| * @returns An object containing the API for managing iframe requests. | ||
| */ | ||
| export default function iframeManagerInit(/*config: OAuthConfig*/) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to keep names as short as possible. Being that all effects are going to follow this pattern of calling a function that returns an API "instance", I don't think there's a need to explicitly have "init" in the name. We can just call it iframeManager or iframeMgmt.
| * | ||
| * @returns An object containing the API for managing iframe requests. | ||
| */ | ||
| export default function iframeManagerInit(/*config: OAuthConfig*/) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also remove the comment /*config: OAuthConfig*/.
| * @returns A Promise that resolves with the query parameters from the redirect URL or rejects on timeout or error. | ||
| */ | ||
| const getAuthCodeByIFrame = (options: { | ||
| url: AuthorizeUrl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make sure to remove the AuthorizeUrl type dependency here.
| * @param options - The options for the iframe request (URL, timeout). | ||
| * @returns A Promise that resolves with the query parameters from the redirect URL or rejects on timeout or error. | ||
| */ | ||
| const getParamsFromIFrame = (options: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I like this name. How about getRedirectParams? The fact that we're using an iframe to do it is inherent in the fact that this is the iframe manager API.
| return { | ||
| getParamsFromIFrame, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a huge fan of this pattern. Can we keep this consistent with our other modules and return the object with the methods defined inline?
| }); | ||
|
|
||
| // Check for standard OAuth error parameters | ||
| if (params.error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block is still quite tied to OAuth related stuff. Let's add error params to the config parameter too. In other words, let's have an array of success params, and an array of error params. That way, this function doesn't need to know how to do anything other than the following:
- Does this URL have any of the provided success params -> resolve with all params as object
- Does this URL have any of the provided error params -> reject with all params as object
| cleanup = () => {}; | ||
| }; | ||
|
|
||
| onLoadHandler = (): void => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the thing we're missing here is waiting for either a success or error param before resolving/rejecting. If I'm reading this right, we are assuming success or failure upon the first redirect. But, this may not always be true. There may be additional redirects on the server-side before the redirect back to the client app.
That's what this was for in the legacy code: https://github.com/ForgeRock/forgerock-javascript-sdk/blob/develop/packages/javascript-sdk/src/oauth2-client/index.ts#L127. So, there's a condition saying, "now that the iframe has loaded a page, does it contain the appropriate success or error param? If not, keep listening for more onload events."
| // Reject with error details from the URL | ||
| reject( | ||
| new Error( | ||
| `Authorization error: ${params.error}. Description: ${params.error_description || 'N/A'}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More "Authorization" specific stuff that we should genericize.
| cleanup(); | ||
| reject({ | ||
| type: 'internal_error', | ||
| message: 'unexpected failure', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have to do it now, but I'd like to think about how we can provide troubleshooting hints in our error messages. This may reduce support tickets for us to give them simple debugging tips, like copy and paste the URL into the browser to see the issue.
ed203dc to
1667343
Compare
create an iframe manager package which is consumed by davinci-client. Updated types throughout the codebase add-headers to files
JIRA Ticket
https://pingidentity.atlassian.net/browse/SDKS-3904
Description
Initial rewrite of iframe manager