Skip to content

Commit

Permalink
revert removing start
Browse files Browse the repository at this point in the history
  • Loading branch information
denysoblohin-okta committed May 25, 2022
1 parent 593e269 commit 9853c75
Show file tree
Hide file tree
Showing 14 changed files with 35 additions and 84 deletions.
12 changes: 3 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ npm install --save @okta/okta-auth-js # requires at least version 5.3.1

`okta-react` provides the necessary tools to build an integration with most common React-based SPA routers.

- [Security](#security) - Accepts [oktaAuth][Okta Auth SDK] instance (**required**, should be started) and additional [configuration](#configuration-options) as props. This component acts as a [React Context Provider][] that maintains the latest [authState][AuthState] and [oktaAuth][Okta Auth SDK] instance for the downstream consumers. This context can be accessed via the [useOktaAuth](#useoktaauth) React Hook, or the [withOktaAuth](#useoktaauth) Higher Order Component wrapper from it's descendant component.
- [Security](#security) - Accepts [oktaAuth][Okta Auth SDK] instance (**required**) and additional [configuration](#configuration-options) as props. This component acts as a [React Context Provider][] that maintains the latest [authState][AuthState] and [oktaAuth][Okta Auth SDK] instance for the downstream consumers. This context can be accessed via the [useOktaAuth](#useoktaauth) React Hook, or the [withOktaAuth](#useoktaauth) Higher Order Component wrapper from it's descendant component.
- [LoginCallback](#logincallback) - A simple component which handles the login callback when the user is redirected back to the application from the Okta login site. `<LoginCallback>` accepts an optional prop `errorComponent` that will be used to format the output for any error in handling the callback. This component will be passed an `error` prop that is an error describing the problem. (see the `<OktaError>` component for the default rendering)

Users of routers other than `react-router` can use [useOktaAuth](#useoktaauth) to see if `authState` is not null and `authState.isAuthenticated` is true. If it is false, you can send them to login via [oktaAuth.signInWithRedirect()](https://github.com/okta/okta-auth-js#signinwithredirectoptions). See the implementation of `<LoginCallback>` as an example.
Expand Down Expand Up @@ -161,7 +161,6 @@ class App extends Component {
clientId: '{clientId}',
redirectUri: window.location.origin + '/login/callback'
});
this.oktaAuth.start();
this.restoreOriginalUri = async (_oktaAuth, originalUri) => {
props.history.replace(toRelativeUrl(originalUri || '/', window.location.origin));
};
Expand Down Expand Up @@ -201,7 +200,6 @@ const oktaAuth = new OktaAuth({
clientId: '{clientId}',
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

const App = () => {
const history = useHistory();
Expand Down Expand Up @@ -387,7 +385,7 @@ export default MessageList = () => {

#### oktaAuth

*(required)* The pre-initialized and pre-started [oktaAuth][Okta Auth SDK] instance. See [Configuration Reference](https://github.com/okta/okta-auth-js#configuration-reference) for details of how to initialize the instance.
*(required)* The pre-initialized [oktaAuth][Okta Auth SDK] instance. See [Configuration Reference](https://github.com/okta/okta-auth-js#configuration-reference) for details of how to initialize the instance.

#### restoreOriginalUri

Expand All @@ -408,7 +406,6 @@ const oktaAuth = new OktaAuth({
clientId: '{clientId}',
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

export default App = () => {
const history = useHistory();
Expand Down Expand Up @@ -440,7 +437,7 @@ export default App = () => {

Assuming you have configured your application to allow the `Authorization code` grant type, you can implement the [PKCE flow](https://github.com/okta/okta-auth-js#pkce) with the following steps:

- Initialize [oktaAuth][Okta Auth SDK] instance (with default PKCE configuration as `true`), start and pass it to the `Security` component.
- Initialize [oktaAuth][Okta Auth SDK] instance (with default PKCE configuration as `true`) and pass it to the `Security` component.
- add `/login/callback` route with [LoginCallback](#logincallback) component to handle login redirect from OKTA.

```jsx
Expand All @@ -451,7 +448,6 @@ const oktaAuth = new OktaAuth({
clientId: '{clientId}',
redirectUri: window.location.origin + '/login/callback',
});
oktaAuth.start();

class App extends Component {
render() {
Expand Down Expand Up @@ -581,7 +577,6 @@ const oktaAuth = new OktaAuth({
clientId: '{clientId}',
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

export default App = () => {
const history = useHistory();
Expand Down Expand Up @@ -626,7 +621,6 @@ import { OktaAuth } from '@okta/okta-auth-js';
import { Security } from '@okta/okta-react';

const oktaAuth = new OktaAuth(oidcConfig);
oktaAuth.start();
export default () => (
<Security oktaAuth={oktaAuth} onAuthRequired={customAuthHandler}>
// children component
Expand Down
1 change: 0 additions & 1 deletion samples/custom-login/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import CorsErrorModal from './CorsErrorModal';
import AuthRequiredModal from './AuthRequiredModal';

const oktaAuth = new OktaAuth(config.oidc);
oktaAuth.start();

const App = () => {
const [corsErrorModalOpen, setCorsErrorModalOpen] = React.useState(false);
Expand Down
1 change: 0 additions & 1 deletion samples/doc-direct-auth/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Protected from './Protected';
import config from './config';

const oktaAuth = new OktaAuth(config.oidc);
oktaAuth.start();

const App = () => {
const history = useHistory();
Expand Down
1 change: 0 additions & 1 deletion samples/doc-embedded-widget/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Protected from './Protected';
import config from './config';

const oktaAuth = new OktaAuth(config.oidc);
oktaAuth.start();

const App = () => {
const history = useHistory();
Expand Down
1 change: 0 additions & 1 deletion samples/okta-hosted-login/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import CorsErrorModal from './CorsErrorModal';
import AuthRequiredModal from './AuthRequiredModal';

const oktaAuth = new OktaAuth(config.oidc);
oktaAuth.start();

const App = () => {
const [corsErrorModalOpen, setCorsErrorModalOpen] = React.useState(false);
Expand Down
1 change: 0 additions & 1 deletion samples/routing/reach-router/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const oktaAuth = new OktaAuth({
clientId: process.env.SPA_CLIENT_ID,
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

function App() {
const restoreOriginalUri = (_oktaAuth: any, originalUri: string) => {
Expand Down
1 change: 0 additions & 1 deletion samples/routing/react-router-dom-v5-hash/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const oktaAuth = new OktaAuth({
clientId: process.env.SPA_CLIENT_ID,
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

function App() {
const history = useHistory();
Expand Down
1 change: 0 additions & 1 deletion samples/routing/react-router-dom-v5/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const oktaAuth = new OktaAuth({
clientId: process.env.SPA_CLIENT_ID,
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

function App() {
const history = useHistory();
Expand Down
1 change: 0 additions & 1 deletion samples/routing/react-router-dom-v6-hash/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const oktaAuth = new OktaAuth({
clientId: process.env.SPA_CLIENT_ID,
redirectUri: window.location.origin + '/login/callback'
});
oktaAuth.start();

function App() {
const navigate = useNavigate();
Expand Down
1 change: 0 additions & 1 deletion samples/routing/react-router-dom-v6/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import Nav from './components/Nav';
import Routes from './components/Routes';

const oktaAuth = new OktaAuth(config.oidc);
oktaAuth.start();

function App() {
const navigate = useNavigate();
Expand Down
14 changes: 2 additions & 12 deletions src/Security.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,8 @@ const Security: React.FC<{
};
oktaAuth.authStateManager.subscribe(handler);

// Check service started
const currentAuthState = oktaAuth.authStateManager.getAuthState();
if (currentAuthState) {
// Service has been started and updated authState
setAuthState(currentAuthState);
} else if (!oktaAuth.isLoginRedirect() && !oktaAuth.authStateManager?._pending?.updateAuthStatePromise) {
// Service has NOT been started
// Need to trigger initial change event and notify user about `oktaAuth.start()`
// Signing out with `clearTokensBeforeRedirect` and background services will not work
oktaAuth.authStateManager.updateAuthState();
console.warn('OktaAuth service should be started outside of Security component.');
}
// Trigger an initial change event to make sure authState is latest
oktaAuth.start();

return () => {
oktaAuth.authStateManager.unsubscribe(handler);
Expand Down
1 change: 0 additions & 1 deletion test/apps/test-harness-app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const oktaAuth = new OktaAuth({
redirectUri,
pkce
});
oktaAuth.start();

ReactDOM.render(
<Router>
Expand Down
5 changes: 3 additions & 2 deletions test/jest/loginCallback.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('<LoginCallback />', () => {
expect(wrapper.text()).toBe('');
});

it('calls handleLoginRedirect when authState is resolved', () => {
it('calls handleLoginRedirect when authState is resolved', async () => {
authState = {
isAuthorized: true
}
Expand All @@ -70,7 +70,8 @@ describe('<LoginCallback />', () => {
</Security>
);
expect(oktaAuth.handleLoginRedirect).toHaveBeenCalledTimes(1);
expect(oktaAuth.start).toHaveBeenCalledTimes(0);
await Promise.resolve();
expect(oktaAuth.start).toHaveBeenCalledTimes(1);
});

describe('shows errors', () => {
Expand Down
78 changes: 27 additions & 51 deletions test/jest/security.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,53 +168,36 @@ describe('<Security />', () => {
expect(console.warn).not.toBeCalled();
});

it('service should be started outside of the <Security />', () => {
it('calls start and updates the context, does NOT call stop', () => {
initialAuthState = null;
// Simulate oktaAuth.start() - it should call oktaAuth.updateAuthState() and save ongoing promise
oktaAuth.authStateManager._pending = {
updateAuthStatePromise: jest.fn(),
canceledTimes: 0
const newAuthState = {
fromUpdateAuthState: true
};
const mockProps = {
oktaAuth,
restoreOriginalUri
};

const MyComponent = jest.fn().mockImplementationOnce(() => {
const oktaProps = useOktaAuth();
expect(oktaProps.authState).toBe(initialAuthState);
return null;
let callback: (state: AuthState | null) => void;
oktaAuth.authStateManager.subscribe = jest.fn().mockImplementation(fn => {
callback = fn;
});
oktaAuth.start = jest.fn().mockImplementation(() => {
callback(newAuthState);
});

const component = mount(
<MemoryRouter>
<Security {...mockProps}>
<MyComponent />
</Security>
</MemoryRouter>
);

expect(oktaAuth.authStateManager.subscribe).toHaveBeenCalledTimes(1);
expect(oktaAuth.start).toHaveBeenCalledTimes(0);
expect(oktaAuth.authStateManager.updateAuthState).toHaveBeenCalledTimes(0);
expect(console.warn).not.toBeCalled();
expect(MyComponent).toHaveBeenCalledTimes(1);
component.unmount();
expect(oktaAuth.stop).toHaveBeenCalledTimes(0);
});

it('if service has not been started outside of the <Security />, calls updateAuthState and produces a warning', () => {
initialAuthState = null;
const mockProps = {
oktaAuth,
restoreOriginalUri
};

const MyComponent = jest.fn().mockImplementationOnce(() => {
const oktaProps = useOktaAuth();
expect(oktaProps.authState).toBe(initialAuthState);
return null;
});
const MyComponent = jest.fn()
// first call
.mockImplementationOnce(() => {
const oktaProps = useOktaAuth();
expect(oktaProps.authState).toBe(initialAuthState);
return null;
})
// second call
.mockImplementationOnce(() => {
const oktaProps = useOktaAuth();
expect(oktaProps.authState).toBe(newAuthState);
return null;
});

const component = mount(
<MemoryRouter>
Expand All @@ -225,11 +208,10 @@ describe('<Security />', () => {
);

expect(oktaAuth.authStateManager.subscribe).toHaveBeenCalledTimes(1);
expect(oktaAuth.start).toHaveBeenCalledTimes(0);
expect(oktaAuth.authStateManager.updateAuthState).toHaveBeenCalledTimes(1);
expect(console.warn).toBeCalled();
expect(MyComponent).toHaveBeenCalledTimes(1);
expect(oktaAuth.start).toHaveBeenCalledTimes(1);
expect(MyComponent).toHaveBeenCalledTimes(2);
component.unmount();
expect(oktaAuth.authStateManager.unsubscribe).toHaveBeenCalledTimes(1);
expect(oktaAuth.stop).toHaveBeenCalledTimes(0);
});

Expand Down Expand Up @@ -260,13 +242,10 @@ describe('<Security />', () => {
callbacks.splice(index, 1);
}
});
oktaAuth.authStateManager.updateAuthState = jest.fn().mockImplementation(() => {
oktaAuth.start = jest.fn().mockImplementation(() => {
stateCount++;
callbacks.map(fn => fn(mockAuthStates[stateCount]));
});
oktaAuth.start = jest.fn().mockImplementation(() => {
oktaAuth.authStateManager.updateAuthState();
});
const mockProps = {
oktaAuth,
restoreOriginalUri
Expand Down Expand Up @@ -299,10 +278,6 @@ describe('<Security />', () => {
</MemoryRouter>
);

act(() => {
oktaAuth.start();
});

expect(callbacks.length).toEqual(2);
expect(oktaAuth.authStateManager.subscribe).toHaveBeenCalledTimes(1);
expect(oktaAuth.start).toHaveBeenCalledTimes(1);
Expand All @@ -316,6 +291,7 @@ describe('<Security />', () => {

component.unmount();
expect(oktaAuth.stop).toHaveBeenCalledTimes(0);
expect(oktaAuth.authStateManager.unsubscribe).toHaveBeenCalledTimes(1);
expect(callbacks.length).toEqual(1);
});

Expand Down

0 comments on commit 9853c75

Please sign in to comment.