OktaDev Schematics 1.2.0 Released!

We released v1.2.0 of our OktaDev Schematics today. This release contains upgrades for our Angular, React, and Vue SDKs. OktaDev Schematics provide an automated way to install and configure our SDKs.

IMO, the biggest feature in this release is continued compatibility with Angular 9. If you’re planning on upgrading to Angular 9, it’d be great if you could try this release.

Create an App with Angular 9

First, create an empty project with Angular CLI. You must add Angular routing for this schematic to work. Any stylesheet types should work.

npm i -g @angular/cli@9.0.0-rc.11
ng new secure-angular --routing
cd secure-angular

Add an OpenID Connect App in Okta

  • Log into the Okta Developer Dashboard and click Applications then Add Application.
  • Choose Single Page App (SPA) as the platform and click Next.
  • Add http://localhost:4200/implicit/callback as a Login redirect URI and click Done.

In your secure-angular project, add @oktadev/schematics:

ng add @oktadev/schematics

You’ll be prompted for an issuer, which you can find in your Okta dashboard at API > Authorization Servers. For the client ID, use the Client ID from the app you created in Okta.

Run ng serve and you should be able to login using the button in the bottom left.


See the project’s README for more information on how to use them. You might also find the blog posts we’ve written useful.

1 Like

Update: I forgot to run npm run build before npm publish, so changes were not included in v1.2.0. I published v1.2.1 to fix the problem.

ng add @oktadev/schematics should pick up the latest version.

1 Like

Thanks for releasing this! :smile:

Does this also work with react?

Yep! See https://github.com/oktadeveloper/schematics#react.

Cool! Another does the sdk support the use of typescript functional components or should you be using class based component?

It uses class-based components now, but we could change it to support both. We’d just need some additional selection logic and templates for that option.

Right now, OktaDev Schematics looks at the dependencies in package.json to determine if it’s plain ol’ React, React with TypeScript, or React Native. Here’s where that logic is:

From there, it has templates for the different options:

Awesome! So if were to create a custom “LoginComponent” to replace the Home.tsx that generated that uses a custom login form instead of the Okta Sign-in Widget, the “LoginComponent” would need to be class based and not functional for everything to wire up correctly when you pass the functional component to the withAuth method. Is this correct?

example

import React, { useState, FormEvent, useEffect } from 'react';
import { FunctionComponent } from 'react';
import { IonContent, IonList, IonInput, IonButton, IonPage, IonItem } from '@ionic/react';  
import { withAuth } from '@okta/okta-react';
import OktaAuth from '@okta/okta-auth-js';

interface LoginProps {
    oktaUrl: string;
    auth: any,
}

const LoginComponent: FunctionComponent<LoginProps> = ({ oktaUrl, auth }) => {

    const [authenticated, setAuthenticated] = useState(false);
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');

    const oktaAuth = new OktaAuth({ url: oktaUrl })

    useEffect(() => {
        console.log('okta url -> ', oktaUrl)
        console.log('login component mounted...');
    }, []);

    useEffect(() => {
        console.log('username change -> ', username);
    }, [username])

    /**
     *
     * @param {FormEvent} event
     */
    const login = (event: FormEvent) => {
        event.preventDefault();
        console.log("authenticating user....");

        if (username !== '' && password !== '') {
            oktaAuth.signIn({ username: username, password: password}).then((response: any) => {
                console.log('response -> ', response);
                console.log(oktaAuth);
                console.log(auth);

            }).catch((error: any) => {
                console.log('error -> ', error);
           });
        }
        else {
            console.log('please enter username and password')
        }
    }

    return (
        <IonPage>
            <IonContent fullscreen={ false } >
                <div style={{ padding: '10%' }}>
                    <form onSubmit={ login }>
                        <div style={{ border: 'solid', borderRadius: '1em', padding: '5px' }}>
                            <IonList>
                                <IonItem>
                                    <IonInput id="username" placeholder="username" color="default" type="text" value={ username } onIonChange={(e) => setUsername((e.target as HTMLInputElement).value)} required={ true }/>
                                </IonItem>
                                <IonItem>
                                    <IonInput id="password" placeholder="password" type="password" value={ password } onIonChange={(e) => setPassword((e.target as HTMLInputElement).value)}/>
                                </IonItem>
                            </IonList>
                            <IonButton type="submit" expand="full">Login</IonButton>
                        </div>
                    </form>
                </div>
             </IonContent>
        </IonPage>
    );
}

export default withAuth(LoginComponent);

I’m not sure. Does it work?

Yes, the component works as is. The catch is that if you expect an idToken back from the inital authentication then you’ll be sad, the idToken is present in that response. You’ll have to use the session token to reach back to Okta to retrieve the idToken or the accessToken if you’re application requires them.