text: // @flow
  import passport from "@outlinewiki/koa-passport";
  import Router from "koa-router";
  import { capitalize } from "lodash";
  import { Strategy as GoogleStrategy } from "passport-google-oauth2";
  import accountProvisioner from "../../commands/accountProvisioner";
  import env from "../../env";
  import {
    GoogleWorkspaceRequiredError,
    GoogleWorkspaceInvalidError,
  } from "../../errors";
  import passportMiddleware from "../../middlewares/passport";
  import { getAllowedDomains } from "../../utils/authentication";
  import { StateStore } from "../../utils/passport";
  
  const router = new Router();
  const providerName = "google";
  const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
  const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET;
  const allowedDomains = getAllowedDomains();
  
  const scopes = [
    "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/userinfo.email",
  ];
  
  export const config = {
    name: "Google",
    enabled: !!GOOGLE_CLIENT_ID,
  };
  
  if (GOOGLE_CLIENT_ID) {
    passport.use(
      new GoogleStrategy(
        {
          clientID: GOOGLE_CLIENT_ID,
          clientSecret: GOOGLE_CLIENT_SECRET,
          callbackURL: `${env.URL}/auth/google.callback`,
          passReqToCallback: true,
          store: new StateStore(),
          scope: scopes,
        },
        async function (req, accessToken, refreshToken, profile, done) {
          try {
            const domain = profile._json.hd;
  
            if (!domain) {
              throw new GoogleWorkspaceRequiredError();
            }
  
            if (allowedDomains.length && !allowedDomains.includes(domain)) {
              throw new GoogleWorkspaceInvalidError();
            }
  
            const subdomain = domain.split(".")[0];
            const teamName = capitalize(subdomain);
  
            const result = await accountProvisioner({
              ip: req.ip,
              team: {
                name: teamName,
                domain,
                subdomain,
              },
              user: {
                name: profile.displayName,
                email: profile.email,
                avatarUrl: profile.picture,
              },
              authenticationProvider: {
                name: providerName,
                providerId: domain,
              },
              authentication: {
                providerId: profile.id,
                accessToken,
                refreshToken,
                scopes,
              },
            });
            return done(null, result.user, result);
          } catch (err) {
            return done(err, null);
          }
        }
      )
    );
  
    router.get(
      "google",
      passport.authenticate(providerName, {
        accessType: "offline",
        prompt: "select_account consent",
      })
    );
  
    router.get("google.callback", passportMiddleware(providerName));
  }
  
  export default router;
  