UNPKG

passport-google-oidc-token

Version:
159 lines (133 loc) 3.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _googleAuthLibrary = require("google-auth-library"); /** * `GoogleOIDCTokenStrategy` constructor. * * The Google OIDC token strategy authenticates using the Google Auth Library * * Applications must supply a `verify` callback which accepts an `accessToken`, * `refreshToken` and service-specific `profile`, and then calls the `cb` * callback supplying a `user`, which should be set to `false` if the * credentials are not valid. If an exception occurred, `err` should be set. * * @param {Object} options * @param {Function} verify * @example * passport.use(new GoogleOIDCTokenStrategy( * { * clientID: '123456789', * }, * (accessToken, refreshToken, profile, cb) => { * User.findOrCreate({ googleId: profile.id }, cb); * } * ); */ class GoogleOIDCTokenStrategy { error = () => {}; fail = () => {}; success = () => {}; constructor(options, verify) { this.client = new _googleAuthLibrary.OAuth2Client(options.clientID); this.clientId = options.clientID; this.name = 'google-oidc-token'; this._verify = verify; if ('passReqToCallback' in options) {} this._passReqToCallback = 'passReqToCallback' in options ? options.passReqToCallback : false; } /** * Authenticate request using Google Auth Library * @param {Object} req */ async authenticate(req) { const idToken = this.lookup(req, 'id_token'); try { const ticket = await this.client.verifyIdToken({ idToken, audience: this.clientId // Specify the CLIENT_ID of the app that accesses the backend }); const payload = ticket.getPayload(); if (!payload) { throw new Error('No payload returned'); } const verifiedFunction = (error, user, info) => { if (error) { return this.error(error); } if (!user) { return this.fail(info); } return this.success(user, info); }; const profile = GoogleOIDCTokenStrategy.parseProfile(payload); if (this._passReqToCallback) { this._verify(req, idToken, profile, verifiedFunction); } else { this._verify(idToken, profile, verifiedFunction); } } catch (err) { this.error(err); } } /** * This method handles searhing the value of provided field in body, query, and header. * * @param {Object} req http request object * @param {String} field * @returns {String} field's value in body, query, or headers */ lookup(req, field) { return req.body && req.body[field] || req.query && req.query[field] || req.headers && req.headers[field]; } /** * Parse profile. * * Parses user profiles as fetched from Google's OpenID Connect-compatible user * info endpoint. * * The amount of detail in the profile varies based on the scopes granted by the * user. The following scope values add additional data: * * `profile` - basic profile information * `email` - email address * * References: * - https://developers.google.com/identity/protocols/OpenIDConnect * * @param {object} payload * @return {object} */ static parseProfile(payload) { const profile = { provider: 'google', id: payload.sub, displayName: payload.name || '', name: undefined, photos: [], emails: [], _json: payload }; if (payload.family_name || payload.given_name) { profile.name = { familyName: payload.family_name, givenName: payload.given_name }; } if (payload.email) { profile.emails = [{ value: payload.email, verified: payload.email_verified }]; } if (payload.picture) { profile.photos = [{ value: payload.picture }]; } return profile; } } exports.default = GoogleOIDCTokenStrategy;