bananaslug
bananaslug

Reputation: 11

Passport.js with openid-client strategy-- TypeError: client must be an instance of openid-client Client

I'm building a MERN stack app using typescript. I'm using passport with openid-client strategy (https://github.com/panva/node-openid-client/blob/master/docs/README.md#strategy) for user auth. I'm getting the following typeError:

TypeError: client must be an instance of openid-client Client

I've tried using Issuer.discover and new Issuer(), and await/async, made sure node and all my packages are up to date, to no avail.

This is the relevant code:

import { Issuer, Strategy, generators } from "openid-client";

const googleClient = Issuer.discover("https://accounts.google.com/.well-known/openid-configuration")
    .then((googleIssuer: { Client: any; }) => {
        return googleIssuer.Client;
    });

It's supposed to return an openid-client Client instance, but it returns a pending promise.

Upvotes: 1

Views: 2694

Answers (2)

bananaslug
bananaslug

Reputation: 11

Solution for others' reference. I had to put everything inside the promise.

Issuer.discover('https://accounts.google.com/.well-known/openid-configuration')
    .then((googleIssuer: { issuer: any; metadata: any; Client: any; }) => {
        // console.log('Discovered issuer %s %O', googleIssuer.issuer, googleIssuer.metadata);
        const client = new googleIssuer.Client({
            client_id: process.env.GOOGLE_ID,
            client_secret: process.env.GOOGLE_SECRET,
            redirect_uris: ['list of URIs here'],
            response_types: ['code token id_token'],
        });

        const params = {
            client_id: process.env.GOOGLE_ID,
            response_type: 'code token id_token',
            scope: 'openid profile email',
            nonce: generators.nonce(),
            redirect_uri: 'URI here',
            state: generators.state(),
            prompt: 'select_account',
            display: 'popup',
            login_hint: 'sub',
        };

        const verify = ( tokenSet: any, userInfo: any, done: (arg0: null, arg1: any) => void ) => {
            console.log('USERINFO: ', userInfo);
            console.log('TOKENSET: ', tokenSet);
            return done(null, tokenSet);
        };

        const options = {
            client,
            params,
        };
        Passport.use('openid-client', new Strategy( options, verify ));
    }).catch((err: any) => {
        if (err) {
            console.log(err);
        }
    });

Upvotes: 0

Hlight
Hlight

Reputation: 9

You can “await” a promise and then it’s return value from the “then” statement will be assigned the value of the googleClient variable.

Try this

import { Issuer, Strategy, generators } from "openid-client";
​
let googleClient;
(async function discoverClient() {
  googleClient = await Issuer.discover("https://accounts.google.com/.well-known/openid-configuration")
  .then((googleIssuer: { Client: any; }) => {
    return googleIssuer.Client;
  });
})();

Some good info on async/await https://javascript.info/async-await

Upvotes: 0

Related Questions