-
Notifications
You must be signed in to change notification settings - Fork 262
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
feat: add myaccount apis #1158
feat: add myaccount apis #1158
Conversation
|
||
if (sdk.options.httpRequestInterceptors) { | ||
for (const interceptor of sdk.options.httpRequestInterceptors) { | ||
interceptor(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.
What is the purpose of the interceptors? To allow for manipulation of the RequestOptions
?
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.
Yep, seems like there is no proper way to manipulate the url (RequestOptions) after moving the logic to sdk layer. Before ciamx fix the browser cors issue, we still need a way to proxy the request. We can keep it as an internal feature first.
7adf860
to
ee92e70
Compare
22fc103
to
f012819
Compare
Codecov Report
@@ Coverage Diff @@
## master #1158 +/- ##
==========================================
- Coverage 93.46% 91.91% -1.55%
==========================================
Files 159 173 +14
Lines 4679 4957 +278
Branches 1081 1116 +35
==========================================
+ Hits 4373 4556 +183
- Misses 288 378 +90
- Partials 18 23 +5
Continue to review full report at Codecov.
|
5d984a5
to
bc57586
Compare
@@ -85,7 +85,8 @@ describe('E2E login', () => { | |||
await TestApp.logoutRedirect(); | |||
}); | |||
|
|||
it('can login to social idp using signin widget (with redirect)', async () => { | |||
// eslint-disable-next-line jasmine/no-disabled-tests | |||
xit('can login to social idp using signin widget (with redirect)', async () => { |
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 there a ticket to track this and re-enable the test?
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.
@@ -99,7 +100,8 @@ describe('E2E login', () => { | |||
await TestApp.logoutRedirect(); | |||
}); | |||
|
|||
it('can login to social idp using signin widget (no redirect)', async () => { | |||
// eslint-disable-next-line jasmine/no-disabled-tests | |||
xit('can login to social idp using signin widget (no redirect)', async () => { |
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 there a ticket to track this and re-enable the test?
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.
dc5b7ea
to
8b9ea19
Compare
lib/myaccount/request.ts
Outdated
if (error?.error?.includes('insufficient_authentication_context')) { | ||
const scopes = decodeToken(accessToken).payload.scp!; | ||
// reauthentication - this call triggers redirect | ||
await getWithRedirect( |
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 seems incorrect. According to this JIRA - https://oktainc.atlassian.net/browse/OKTA-460659,
When a response includes insufficient_authentication_context that should trigger a new interact/authorize request including the max_age parameter as defined in the response
In our case, we need to call interact
again instead of the getWithRedirect
The current experience redirects the user to okta hosted page which is undesired behavior.
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.
Updated to throw error from SDK layer, and handle it via different re-authentication approaches at sample app layer.
653f3f7
to
9876a83
Compare
80e63ac
to
c6a97d0
Compare
e15ab14
to
9dd11c1
Compare
9dd11c1
to
91f08a3
Compare
lib/myaccount/README.md
Outdated
|
||
## Introduction | ||
|
||
MyAccount APIs enables everything needed for the customer's end user to manage one's account. The API assumes the access token is obtained through the OAuth2 either by the classic or IDX flow. |
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.
MyAccount APIs enables everything needed for the customer's end user to manage one's account. The API assumes the access token is obtained through the OAuth2 either by the classic or IDX flow. | |
MyAccount APIs enables end user account management in SPA applications. The API requires an access token obtained via OAuth flows with additional [scopes](#scopes) |
lib/myaccount/README.md
Outdated
|
||
## Scopes | ||
|
||
Certain token scopes will be needed to gain the permission to read/manage the account resources: |
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.
Certain token scopes will be needed to gain the permission to read/manage the account resources: | |
The following scopes are required for permission to read/write the resources exposed by the MyAccount API: |
lib/myaccount/README.md
Outdated
<script src="https://global.oktacdn.com/okta-auth-js/6.7.0/okta-auth-js.min.js" type="text/javascript"></script> | ||
``` | ||
|
||
> :warning: The version shown in this sample may be older than the current version. We recommend using the highest version available |
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.
Move this warning into the html snippet above as a comment, or move it above the snippet. I think if it's below it's easy to miss
lib/myaccount/README.md
Outdated
|
||
## Handling `insufficient_authentication_context` error | ||
|
||
Re-Authentication will be needed when request requires higher assurance than provided by the access token. MyAccount API methods throws `AuthApiError` with `insufficient_authentication_context` in `errorSummary` and `max_age` in `meta` field to indicate the downstream applications to start a re-authentication flow. |
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.
Re-Authentication will be needed when request requires higher assurance than provided by the access token. MyAccount API methods throws `AuthApiError` with `insufficient_authentication_context` in `errorSummary` and `max_age` in `meta` field to indicate the downstream applications to start a re-authentication flow. | |
For additional security, the MyAccount API requires a higher assurance level to protect the end user's account from being manipulated by malicious actors. If the `access token` provided does not meet the required assurance level, an error will be thrown to prompt the user to re-authenticate. Applications consuming the MyAccount API will need to handle this error condition. When this occurs, `myaccount` methods will throw an `AuthApiError` with `insufficient_authentication_context` in `errorSummary` and `max_age` in `meta` field, like so: |
lib/myaccount/README.md
Outdated
|
||
Re-Authentication will be needed when request requires higher assurance than provided by the access token. MyAccount API methods throws `AuthApiError` with `insufficient_authentication_context` in `errorSummary` and `max_age` in `meta` field to indicate the downstream applications to start a re-authentication flow. | ||
|
||
### AuthApiError example: |
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.
remove this header
lib/myaccount/README.md
Outdated
} | ||
``` | ||
|
||
Re-authentication Approaches: |
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.
Re-authentication Approaches: | |
## Re-authentication Approaches: |
|
||
`App.jsx` is the entry point of the whole app, it manages the transaction state of the whole app and shares it via React context. Based on the current transaction status, it also redirects the app to the proper routes. | ||
This sample app demostrates the best practices for integrating Authentication into your React SAP via the embedded Auth SDK (@okta/okta-auth-js). It dynamically renders the form by following responses from [Okta's Identity Engine][]. Policy changes, like adding extra authenticator for MFA, can be reflected in this sample app with no code change. |
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 sample app demostrates the best practices for integrating Authentication into your React SAP via the embedded Auth SDK (@okta/okta-auth-js). It dynamically renders the form by following responses from [Okta's Identity Engine][]. Policy changes, like adding extra authenticator for MFA, can be reflected in this sample app with no code change. | |
This sample app demonstrates the best practices for integrating Authentication into your React SPA via the embedded Auth SDK (@okta/okta-auth-js). It dynamically renders the form by following responses from [Okta's Identity Engine][]. Policy changes, like adding extra authenticator for MFA, can be reflected in this sample app with no code change. |
.husky/pre-commit
Outdated
#!/bin/sh | ||
. "$(dirname "$0")/_/husky.sh" | ||
|
||
npx lint-staged |
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 we adding this with this PR? Is this required for myaccount? I'd prefer to have a separate conversation about pre-commit hooks and handle it in a separate PR. Also why npx instead of yarn?
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 feel we will want to take doc/code consistency as the first priority. In this PR, docs for myaccount is generated from code/types, and it's easy to miss to run doc update script when code changes happen. This pre-commit hook here is a solution to keep things in sync.
I understand it may affect a bit devex, but here I would prefer to take consistency over devex.
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.
Could this be done as a pre-push step instead of pre-commit? When rebasing we do a lot of commits, but there is only one push at the end.
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.
pre-push cannot just handle staged files, this lint staged won't run scripts when no file matches the regex.
@@ -6,7 +6,7 @@ export TEST_SUITE_TYPE="junit" | |||
export TEST_RESULT_FILE_DIR="${REPO}/build2/reports/unit" | |||
|
|||
export CI=true | |||
export ISSUER=https://oie-signin-widget.okta.com/oauth2/default | |||
export ISSUER=https://oie-signin-widget.okta.com |
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.
does myaccount only work with org auth server?
what about our other integration tests? Are we introducing a gap by not testing against custom auth server?
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.
does myaccount only work with org auth server?
Yes, sadly it is what current how myaccount api works
what about our other integration tests? Are we introducing a gap by not testing against custom auth server?
I don't think we are testing any custom AS specific features, @vijetmahabaleshwar-okta maybe you can share some insights
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.
No, we aren't testing any custom AS specific features. Org AS should work for our tests.
lib/myaccount/index.ts
Outdated
@@ -0,0 +1,3 @@ | |||
export * from './profileApi'; | |||
export * from './emailApi'; | |||
export * from './phoneApi'; |
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.
should also export types here?
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.
yes they are build there from the source file "types.ts". Don't you want export * from './types'
in the index file?
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.
added, also added tsd to verify types
jest.esm.mjs
Outdated
@@ -15,6 +15,9 @@ | |||
const OktaAuth = process.env.BUNDLE_ENV === 'browser' ? | |||
`<rootDir>/build/esm/browser/index.js` : | |||
`<rootDir>/build/esm/node/index.js`; | |||
const MyaccountEntry = process.env.BUNDLE_ENV === 'browser' ? |
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.
nit: prefer "MyAccountEntry"
lib/.eslintrc.js
Outdated
@@ -18,6 +18,8 @@ module.exports = { | |||
}, | |||
rules: { | |||
"node/no-unsupported-features/es-syntax": 0, | |||
"@typescript-eslint/no-non-null-assertion": 0, | |||
"no-use-before-define": 0, |
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.
are there many instances of this? we are currently disabling the rule on a case by case basis since this could be hiding an error. particularly the non-null assertion could be better handled with some code refactor, so I see it as mostly a debt item to refactor the code to have early return or type guard functions so that TS knows whether a variable can be null or not
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.
good call, will take a closer look
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.
removed, and replaced with comment in code
@@ -87,6 +88,7 @@ export function buildOptions(args: OktaAuthOptions = {}): OktaAuthOptions { | |||
ignoreSignature: !!args.ignoreSignature, | |||
|
|||
// Server-side web applications | |||
clientSecret: args.clientSecret | |||
clientSecret: args.clientSecret, | |||
setLocation: args.setLocation |
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.
should add documentation in README for these new 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.
readme option added
@@ -201,7 +201,7 @@ class OktaAuth implements OktaAuthInterface, SigninAPI, SignoutAPI { | |||
}; | |||
|
|||
// Add shims for compatibility, these will be removed in next major version. OKTA-362589 | |||
Object.assign(this.options.storageUtil, { | |||
Object.assign(this.options.storageUtil || {}, { |
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.
under what condition can options.storageUtil be undefined?
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.
required after typescript upgrade
@@ -69,7 +76,13 @@ export function httpRequest(sdk: OktaAuthHttpInterface, options: RequestOptions) | |||
if (res && isString(res)) { | |||
res = JSON.parse(res); | |||
if (res && typeof res === 'object' && !res.headers) { | |||
res.headers = resp.headers; | |||
if (Array.isArray(res)) { |
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.
Which response is returning an array at the top-level?
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.
/idp/myaccount/emails
and /idp/myaccount/phones
@@ -23,6 +23,8 @@ export function getNativeConsole() { | |||
|
|||
export function getConsole() { | |||
var nativeConsole = getNativeConsole(); | |||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | |||
// @ts-ignore |
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 needed?
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.
after typescript upgrade
@@ -46,7 +64,7 @@ | |||
"test:server": "jest --config ./jest.server.js", | |||
"test:report": "yarn test --ci --silent || true", | |||
"test:samples": "yarn workspace @okta/test.e2e.samples start", | |||
"test:integration": "jest --config ./jest.integration.js", | |||
"test:integration": "jest --runInBand --config ./jest.integration.js", |
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 reason these tests cannot run in parallel?
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.
myaccount api need to be tested in a crud flow, run it in parallel causes flakiness.
OKTA-486697 <<<Jenkins Check-In of Tested SHA: e8ddce4 for [email protected]>>> Artifact: okta-auth-js Files changed count: 208 PR Link: #1158
In this PR:
@okta/okta-auth-js/myaccount
samples/generated/react-embedded-auth-with-sdk