2024-02-28 08:17:02 +00:00
|
|
|
import { joinWithProvider, loginWithProvider } from '@hcengineering/account'
|
2024-03-26 15:07:58 +00:00
|
|
|
import { concatLink, MeasureContext } from '@hcengineering/core'
|
|
|
|
import Router from 'koa-router'
|
2024-02-28 08:17:02 +00:00
|
|
|
import { Db } from 'mongodb'
|
2024-03-26 15:07:58 +00:00
|
|
|
import { Strategy as GitHubStrategy } from 'passport-github2'
|
2024-02-28 08:17:02 +00:00
|
|
|
import { Passport } from '.'
|
|
|
|
|
|
|
|
export function registerGithub (
|
2024-04-03 14:52:38 +00:00
|
|
|
measureCtx: MeasureContext,
|
2024-02-28 08:17:02 +00:00
|
|
|
passport: Passport,
|
|
|
|
router: Router<any, any>,
|
|
|
|
accountsUrl: string,
|
|
|
|
db: Db,
|
|
|
|
productId: string,
|
|
|
|
frontUrl: string
|
|
|
|
): string | undefined {
|
|
|
|
const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID
|
|
|
|
const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET
|
|
|
|
|
|
|
|
const redirectURL = '/auth/github/callback'
|
|
|
|
if (GITHUB_CLIENT_ID === undefined || GITHUB_CLIENT_SECRET === undefined) return
|
|
|
|
passport.use(
|
|
|
|
new GitHubStrategy(
|
|
|
|
{
|
|
|
|
clientID: GITHUB_CLIENT_ID,
|
|
|
|
clientSecret: GITHUB_CLIENT_SECRET,
|
|
|
|
callbackURL: concatLink(accountsUrl, redirectURL),
|
|
|
|
passReqToCallback: true
|
|
|
|
},
|
|
|
|
function (req: any, accessToken: string, refreshToken: string, profile: any, done: any) {
|
|
|
|
done(null, profile)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
router.get('/auth/github', async (ctx, next) => {
|
|
|
|
const state = ctx.query?.inviteId
|
|
|
|
passport.authenticate('github', { scope: ['user:email'], session: true, state })(ctx, next)
|
|
|
|
})
|
|
|
|
|
|
|
|
router.get(
|
|
|
|
redirectURL,
|
|
|
|
passport.authenticate('github', { failureRedirect: concatLink(frontUrl, '/login'), session: true }),
|
|
|
|
async (ctx, next) => {
|
2024-03-02 06:20:33 +00:00
|
|
|
const email = ctx.state.user.emails?.[0]?.value ?? `github:${ctx.state.user.username}`
|
2024-02-28 08:17:02 +00:00
|
|
|
const [first, last] = ctx.state.user.displayName.split(' ')
|
|
|
|
if (email !== undefined) {
|
2024-04-03 14:52:38 +00:00
|
|
|
try {
|
|
|
|
if (ctx.query?.state != null) {
|
|
|
|
const loginInfo = await joinWithProvider(measureCtx, db, productId, email, first, last, ctx.query.state, {
|
|
|
|
githubId: ctx.state.user.id
|
|
|
|
})
|
|
|
|
if (ctx.session != null) {
|
|
|
|
ctx.session.loginInfo = loginInfo
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const loginInfo = await loginWithProvider(measureCtx, db, productId, email, first, last, {
|
|
|
|
githubId: ctx.state.user.id
|
|
|
|
})
|
|
|
|
if (ctx.session != null) {
|
|
|
|
ctx.session.loginInfo = loginInfo
|
|
|
|
}
|
2024-02-28 08:17:02 +00:00
|
|
|
}
|
2024-04-03 14:52:38 +00:00
|
|
|
// Successful authentication, redirect to your application
|
|
|
|
ctx.redirect(concatLink(frontUrl, '/login/auth'))
|
|
|
|
} catch (err: any) {
|
2024-04-25 15:15:11 +00:00
|
|
|
measureCtx.error('failed to auth', err)
|
2024-02-28 08:17:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
await next()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
return 'github'
|
|
|
|
}
|