import jwt from "jwt-simple"
import { GraphQLString, GraphQLNonNull, GraphQLEnumType } from "graphql"
import config from "config"
import { includes } from "lodash"

const { HMAC_SECRET } = config

const isExternalOperatorAuthorized = (sale, mePartners) => {
  return includes(mePartners.map(p => p._id), sale.partner._id)
}

export default {
  type: GraphQLString,
  description: "Creates, and authorizes, a JWT custom for Causality",
  args: {
    role: {
      type: new GraphQLEnumType({
        name: "Role",
        values: {
          PARTICIPANT: { value: "PARTICIPANT" },
          OPERATOR: { value: "OPERATOR" },
        },
      }),
      description: "",
    },
    sale_id: {
      type: new GraphQLNonNull(GraphQLString),
      description: "The id of the auction to participate in",
    },
  },
  resolve: (
    root,
    options,
    request,
    {
      rootValue: {
        accessToken,
        meLoader,
        meBiddersLoader,
        mePartnersLoader,
        saleLoader,
      },
    }
  ) => {
    // Observer role for logged out users
    if (!accessToken) {
      return saleLoader(options.sale_id).then(sale =>
        jwt.encode(
          {
            aud: "auctions",
            role: "observer",
            userId: null,
            saleId: sale._id,
            bidderId: null,
            iat: new Date().getTime(),
          },
          HMAC_SECRET
        )
      )

      // For logged in and...
    } else if (options.role === "PARTICIPANT") {
      return Promise.all([
        saleLoader(options.sale_id),
        meLoader(),
        meBiddersLoader({ sale_id: options.sale_id }),
      ]).then(([sale, me, bidders]) => {
        if (bidders.length && bidders[0].qualified_for_bidding) {
          return jwt.encode(
            {
              aud: "auctions",
              role: "bidder",
              userId: me._id,
              saleId: sale._id,
              bidderId: bidders[0].id,
              iat: new Date().getTime(),
            },
            HMAC_SECRET
          )
        }
        return jwt.encode(
          {
            aud: "auctions",
            role: "observer",
            userId: me._id,
            saleId: sale._id,
            bidderId: null,
            iat: new Date().getTime(),
          },
          HMAC_SECRET
        )
      })
    // Operator role if logged in as an admin or if user has access to partner
    } else if (options.role === "OPERATOR") {
      return Promise.all([saleLoader(options.sale_id), meLoader()]).then(
        ([sale, me]) => {
          if (me.type === "Admin") {
            return jwt.encode(
              {
                aud: "auctions",
                role: "operator",
                userId: me._id,
                saleId: sale._id,
                bidderId: me.paddle_number,
                iat: new Date().getTime(),
              },
              HMAC_SECRET
            )
          }
          return mePartnersLoader({ "partner_ids[]": sale.partner._id }).then(
            mePartners => {
              // Check if current user has access to partner running the sale
              if (!isExternalOperatorAuthorized(sale, mePartners)) {
                throw new Error("Unauthorized to be operator")
              }
              return jwt.encode(
                {
                  aud: "auctions",
                  role: "external_operator",
                  userId: me._id,
                  saleId: sale._id,
                  bidderId: me.paddle_number,
                  iat: new Date().getTime(),
                },
                HMAC_SECRET
              )
            }
          )
        }
      )
    }
  },
}

@@ -127,201 +127,39 @@
 ig%22%0A
-import %7B includes %7D from %22lodash%22%0A%0Aconst %7B HMAC_SECRET %7D = config%0A%0Aconst isExternalOperatorAuthorized = (sale, mePartners) =%3E %7B%0A  return includes(mePartners.map(p =%3E p._id), sale.partner._id)%0A%7D
+%0Aconst %7B HMAC_SECRET %7D = config
 %0A%0Aex
@@ -2146,24 +2146,26 @@
      %7D)%0A    
+  
 // Operator 
@@ -2953,55 +2953,31 @@
 if (
-!isExternalOperatorAuthorized(sale, mePartners)
+mePartners.length === 0
 ) %7B%0A

Streamline checking if user has partners for external_operator role