'use strict'

const _ = require('lodash')
const _h = require('./_helpers')
const crypto = require('crypto')
const jwt = require('jsonwebtoken')
const ObjectID = require('mongodb').ObjectID

const mongoDbSystemDbs = ['admin', 'config', 'local']

exports.handler = async (event, context) => {
  if (event.source === 'aws.events') { return }

  try {
    const authHeaderParts = _.get(event, 'headers.Authorization', '').split(' ')
    if (authHeaderParts.length !== 2 || authHeaderParts[0].toLowerCase() !== 'bearer') { return _h.error([400, 'No key']) }

    const key = authHeaderParts[1]
    if (key.length !== 24 && key.length !== 48) { return _h.error([400, 'Invalid key']) }

    var authFilter = {}
    const connection = await _h.db('entu')

    if (key.length === 24) {
      const session = await connection.collection('session').findOneAndUpdate({ _id: new ObjectID(key), deleted: { $exists: false } }, { $set: { deleted: new Date() } })

      if (!session.value) { return _h.error([400, 'No session']) }

      authFilter['private.entu_user.string'] = _.get(session, 'value.user.email')
    } else {
      authFilter['private.entu_api_key.string'] = crypto.createHash('sha256').update(key).digest('hex')
    }

    const jwtSecret = await _h.ssmParameter('entu-api-jwt-secret')

    const dbs = await connection.admin().listDatabases()
    let accounts = []

    for (let i = 0; i < dbs.databases.length; i++) {
      const account = _.get(dbs, ['databases', i, 'name'])
      if (mongoDbSystemDbs.includes(account)) { continue }

      const accountCon = await _h.db(account)
      const person = await accountCon.collection('entity').findOne(authFilter, { projection: { _id: true } })

      if (person) {
        accounts.push({
          _id: person._id.toString(),
          account: account,
          token: jwt.sign({}, jwtSecret, {
            issuer: account,
            audience: _.get(event, 'requestContext.identity.sourceIp'),
            subject: person._id.toString(),
            expiresIn: '48h'
          })
        })
      }
    }

    return _h.json(_.mapValues(_.groupBy(_.compact(accounts), 'account'), (o) => _.first(o)))
  } catch (e) {
    return _h.error(e)
  }
}

@@ -1363,10 +1363,10 @@
 s = 
-%5B%5D
+%7B%7D
 %0A%0A  
@@ -1712,101 +1712,34 @@
 rson
-) %7B%0A        accounts.push(%7B%0A          _id: person._id.toString(),%0A          account: account,
+ && ! accounts%5Baccount%5D) %7B
 %0A   
@@ -1747,16 +1747,21 @@
     
- 
+const
  token
-:
+ =
  jwt
@@ -1793,18 +1793,16 @@
         
-  
 issuer: 
@@ -1810,18 +1810,16 @@
 ccount,%0A
-  
         
@@ -1890,18 +1890,16 @@
         
-  
 subject:
@@ -1922,18 +1922,16 @@
 ring(),%0A
-  
         
@@ -1953,28 +1953,146 @@
 8h'%0A        
-  
 %7D)
+%0A%0A        accounts%5Baccount%5D = %7B%0A          _id: person._id.toString(),%0A          account: account,%0A          token: token
 %0A        %7D)%0A
@@ -2089,17 +2089,16 @@
        %7D
-)
 %0A      %7D
@@ -2128,80 +2128,30 @@
 son(
-_.mapValues(_.groupBy(_.compact(accounts), 'account'), (o) =%3E _.first(o)
+Object.values(accounts
 ))%0A 

Set /auth to return tokens as Array