All files / util githubAuth.js

0% Statements 0/46
0% Branches 0/10
0% Functions 0/14
0% Lines 0/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91                                                                                                                                                                                     
/**
 * githubAuth utility
 */
 
module.exports = function(config) {
  'use strict'
 
  const lib = {}
  const auth = require('./auth')
  const passport = require('passport')
  const GitHubStrategy = require('passport-github').Strategy
  const debug = require('debug')('crowi:lib:githubAuth')
  const octokit = require('@octokit/rest')()
  const { getContinueUrl } = require('../util/url')
 
  lib.PROVIDER = 'github'
 
  function useGitHubStrategy(config, callbackQuery) {
    passport.use(
      new GitHubStrategy(
        {
          clientID: config.crowi['github:clientId'],
          clientSecret: config.crowi['github:clientSecret'],
          callbackURL: `${config.crowi['app:url']}/github/callback${callbackQuery}`,
          scope: ['user:email', 'read:org'],
        },
        function(accessToken, refreshToken, profile, callback) {
          debug('profile', profile)
          octokit.authenticate({ type: 'oauth', token: accessToken })
          octokit.users
            .getOrgs({})
            .then(data => data.data.map(org => org.login))
            .then(orgs => {
              debug('crowi:orgs', orgs)
              callback(null, {
                token: accessToken,
                user_id: profile.id,
                email: profile.emails.filter(v => v.primary)[0].value,
                name: profile.displayName || '',
                picture: profile.photos[0].value,
                organizations: orgs,
              })
            })
        },
      ),
    )
  }
 
  lib.authenticate = function(req, res, next) {
    const continueUrl = getContinueUrl(req)
    const query = continueUrl === '/' ? '' : `?continue=${continueUrl}`
    useGitHubStrategy(config, query)
    passport.authenticate('github')(req, res, next)
  }
 
  lib.getOrganization = () => {}
 
  lib.reauth = async function(id, { accessToken }) {
    try {
      octokit.authenticate({ type: 'oauth', token: accessToken })
      const {
        data: { id: userId },
      } = await octokit.users.get({})
      const { data = [] } = await octokit.users.getOrgs({})
      const orgs = data.map(org => org.login)
      const organization = config.crowi['github:organization']
      const success = id === String(userId) && (!organization || orgs.includes(organization))
      const tokens = { accessToken }
      return { success, tokens }
    } catch (err) {
      debug('Error on reauthenticating', err)
      return { success: false }
    }
  }
 
  lib.handleCallback = function(req, res, next) {
    return function(callback) {
      useGitHubStrategy(config)
      passport.authenticate('github', function(err, user, info) {
        if (err) {
          return callback(err, null)
        }
        auth.saveTokenToSession(req, lib.PROVIDER, { accessToken: user.token })
        return callback(err, user)
      })(req, res, next)
    }
  }
 
  return lib
}