Move old backend code to old_src folder

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2020-07-24 21:06:55 +02:00
parent c42d2223e8
commit 7b9f9a487b
No known key found for this signature in database
GPG key ID: 6017AF117F9756CB
97 changed files with 7 additions and 7 deletions

View file

@ -0,0 +1,41 @@
import { NextFunction, Request, Response, Router } from 'express'
import passport from 'passport'
import { Strategy as DropboxStrategy } from 'passport-dropbox-oauth2'
import { config } from '../../../config'
import { User } from '../../../models'
import { AuthMiddleware } from '../interface'
import { passportGeneralCallback } from '../utils'
export const dropboxAuth = Router()
export const DropboxMiddleware: AuthMiddleware = {
getMiddleware (): Router {
passport.use(new DropboxStrategy({
apiVersion: '2',
clientID: config.dropbox.clientID,
clientSecret: config.dropbox.clientSecret,
callbackURL: config.serverURL + '/auth/dropbox/callback'
}, (
accessToken: string,
refreshToken: string,
profile,
done: (err?: Error | null, user?: User) => void
): void => {
// the Dropbox plugin wraps the email addresses in an object
// see https://github.com/florianheinemann/passport-dropbox-oauth2/blob/master/lib/passport-dropbox-oauth2/strategy.js#L146
profile.emails = profile.emails.map(element => element.value)
passportGeneralCallback(accessToken, refreshToken, profile, done)
}))
dropboxAuth.get('/auth/dropbox', function (req: Request, res: Response, next: NextFunction) {
passport.authenticate('dropbox-oauth2')(req, res, next)
})
dropboxAuth.get('/auth/dropbox/callback',
passport.authenticate('dropbox-oauth2', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
return dropboxAuth
}
}

View file

@ -0,0 +1,95 @@
import { NextFunction, Request, Response, Router } from 'express'
import passport from 'passport'
import { Strategy as LocalStrategy } from 'passport-local'
import validator from 'validator'
import { config } from '../../../config'
import { errors } from '../../../errors'
import { logger } from '../../../logger'
import { User } from '../../../models'
import { urlencodedParser } from '../../utils'
import { AuthMiddleware } from '../interface'
const emailAuth = Router()
export const EmailMiddleware: AuthMiddleware = {
getMiddleware (): Router {
passport.use(new LocalStrategy({
usernameField: 'email'
}, function (email: string, password: string, done) {
if (!validator.isEmail(email)) return done(null, false)
User.findOne({
where: {
email: email
}
}).then(function (user: User) {
if (!user) return done(null, false)
user.verifyPassword(password).then(verified => {
if (verified) {
return done(null, user)
} else {
logger.warn('invalid password given for %s', user.email)
return done(null, false)
}
})
}).catch(function (err: Error) {
logger.error(err)
return done(err)
})
}))
if (config.allowEmailRegister) {
emailAuth.post('/register', urlencodedParser, function (req: Request, res: Response, _: NextFunction) {
if (!req.body.email || !req.body.password) {
errors.errorBadRequest(res)
return
}
if (!validator.isEmail(req.body.email)) {
errors.errorBadRequest(res)
return
}
User.findOrCreate({
where: {
email: req.body.email
},
defaults: {
password: req.body.password
}
}).then(function ([user, created]: [User, boolean]) {
if (user) {
if (created) {
logger.debug('user registered: ' + user.id)
req.flash('info', "You've successfully registered, please signin.")
return res.redirect(config.serverURL + '/')
} else {
logger.debug('user found: ' + user.id)
req.flash('error', 'This email has been used, please try another one.')
return res.redirect(config.serverURL + '/')
}
}
req.flash('error', 'Failed to register your account, please try again.')
return res.redirect(config.serverURL + '/')
}).catch(function (err) {
logger.error('auth callback failed: ' + err)
errors.errorInternalError(res)
})
})
}
emailAuth.post('/login', urlencodedParser, function (req: Request, res: Response, next: NextFunction) {
if (!req.body.email || !req.body.password) {
errors.errorBadRequest(res)
return
}
if (!validator.isEmail(req.body.email)) {
errors.errorBadRequest(res)
return
}
passport.authenticate('local', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/',
failureFlash: 'Invalid email or password.'
})(req, res, next)
})
return emailAuth
}
}

View file

@ -0,0 +1,31 @@
import passport from 'passport'
import { config } from '../../../config'
import { AuthMiddleware } from '../interface'
import { Router } from 'express'
import { passportGeneralCallback } from '../utils'
import { Strategy as FacebookStrategy } from 'passport-facebook'
export const FacebookMiddleware: AuthMiddleware = {
getMiddleware (): Router {
const facebookAuth = Router()
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.serverURL + '/auth/facebook/callback'
}, passportGeneralCallback
))
facebookAuth.get('/auth/facebook', function (req, res, next) {
passport.authenticate('facebook')(req, res, next)
})
// facebook auth callback
facebookAuth.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
return facebookAuth
}
}

View file

@ -0,0 +1,36 @@
import { Router } from 'express'
import passport from 'passport'
import { Strategy as GithubStrategy } from 'passport-github'
import { config } from '../../../config'
import { response } from '../../../response'
import { AuthMiddleware } from '../interface'
import { passportGeneralCallback } from '../utils'
export const GithubMiddleware: AuthMiddleware = {
getMiddleware (): Router {
const githubAuth = Router()
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.serverURL + '/auth/github/callback'
}, passportGeneralCallback))
githubAuth.get('/auth/github', function (req, res, next) {
passport.authenticate('github')(req, res, next)
})
// github auth callback
githubAuth.get('/auth/github/callback',
passport.authenticate('github', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
// github callback actions
githubAuth.get('/auth/github/callback/:noteId/:action', response.githubActions)
return githubAuth
}
}

View file

@ -0,0 +1,41 @@
import { Router } from 'express'
import passport from 'passport'
import { Strategy as GitlabStrategy } from 'passport-gitlab2'
import { config } from '../../../config'
import { response } from '../../../response'
import { AuthMiddleware } from '../interface'
import { passportGeneralCallback } from '../utils'
export const GitlabMiddleware: AuthMiddleware =
{
getMiddleware (): Router {
const gitlabAuth = module.exports = Router()
passport.use(new GitlabStrategy({
baseURL: config.gitlab.baseURL,
clientID: config.gitlab.clientID,
clientSecret: config.gitlab.clientSecret,
scope: config.gitlab.scope,
callbackURL: config.serverURL + '/auth/gitlab/callback'
}, passportGeneralCallback))
gitlabAuth.get('/auth/gitlab', function (req, res, next) {
passport.authenticate('gitlab')(req, res, next)
})
// gitlab auth callback
gitlabAuth.get('/auth/gitlab/callback',
passport.authenticate('gitlab', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
if (!config.gitlab.scope || config.gitlab.scope === 'api'
) {
// gitlab callback actions
gitlabAuth.get('/auth/gitlab/callback/:noteId/:action', response.gitlabActions)
}
return gitlabAuth
}
}

View file

@ -0,0 +1,44 @@
import { Router } from 'express'
import passport from 'passport'
import * as Google from 'passport-google-oauth20'
import { config } from '../../../config'
import { AuthMiddleware } from '../interface'
import { passportGeneralCallback } from '../utils'
const googleAuth = Router()
export const GoogleMiddleware: AuthMiddleware = {
getMiddleware: function (): Router {
passport.use(new Google.Strategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.serverURL + '/auth/google/callback',
userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo'
}, (
accessToken: string,
refreshToken: string,
profile,
done) => {
/*
This ugly hack is neccessary, because the Google Strategy wants a done-callback with an err as Error | null | undefined
but the passportGeneralCallback (and every other PassportStrategy) want a done-callback with err as string | Error | undefined
Note the absence of null. The lambda converts all `null` to `undefined`.
*/
passportGeneralCallback(accessToken, refreshToken, profile, (err?, user?) => {
done(err === null ? undefined : err, user)
})
}))
googleAuth.get('/auth/google', function (req, res, next) {
const authOpts = { scope: ['profile'], hostedDomain: config.google.hostedDomain }
passport.authenticate('google', authOpts)(req, res, next)
})
googleAuth.get('/auth/google/callback',
passport.authenticate('google', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
return googleAuth
}
}

View file

@ -0,0 +1,69 @@
import { Request, Response, Router } from 'express'
import passport from 'passport'
import { config } from '../../config'
import { logger } from '../../logger'
import { User } from '../../models'
import { FacebookMiddleware } from './facebook'
import { TwitterMiddleware } from './twitter'
import { GithubMiddleware } from './github'
import { GitlabMiddleware } from './gitlab'
import { DropboxMiddleware } from './dropbox'
import { GoogleMiddleware } from './google'
import { LdapMiddleware } from './ldap'
import { SamlMiddleware } from './saml'
import { OAuth2Middleware } from './oauth2'
import { EmailMiddleware } from './email'
import { OPenIDMiddleware } from './openid'
const AuthRouter = Router()
// serialize and deserialize
passport.serializeUser(function (user: User, done) {
logger.info('serializeUser: ' + user.id)
return done(null, user.id)
})
passport.deserializeUser(function (id: string, done) {
User.findOne({
where: {
id: id
}
}).then(function (user) {
// Don't die on non-existent user
if (user == null) {
// The extra object with message doesn't exits in @types/passport
return done(null, false) // , { message: 'Invalid UserID' })
}
logger.info('deserializeUser: ' + user.id)
return done(null, user)
}).catch(function (err) {
logger.error(err)
return done(err, null)
})
})
if (config.isFacebookEnable) AuthRouter.use(FacebookMiddleware.getMiddleware())
if (config.isTwitterEnable) AuthRouter.use(TwitterMiddleware.getMiddleware())
if (config.isGitHubEnable) AuthRouter.use(GithubMiddleware.getMiddleware())
if (config.isGitLabEnable) AuthRouter.use(GitlabMiddleware.getMiddleware())
if (config.isDropboxEnable) AuthRouter.use(DropboxMiddleware.getMiddleware())
if (config.isGoogleEnable) AuthRouter.use(GoogleMiddleware.getMiddleware())
if (config.isLDAPEnable) AuthRouter.use(LdapMiddleware.getMiddleware())
if (config.isSAMLEnable) AuthRouter.use(SamlMiddleware.getMiddleware())
if (config.isOAuth2Enable) AuthRouter.use(OAuth2Middleware.getMiddleware())
if (config.isEmailEnable) AuthRouter.use(EmailMiddleware.getMiddleware())
if (config.isOpenIDEnable) AuthRouter.use(OPenIDMiddleware.getMiddleware())
// logout
AuthRouter.get('/logout', function (req: Request, res: Response) {
if (config.debug && req.isAuthenticated()) {
if (req.user !== undefined) {
logger.debug('user logout: ' + req.user.id)
}
}
req.logout()
res.redirect(config.serverURL + '/')
})
export { AuthRouter }

View file

@ -0,0 +1,5 @@
import { Router } from 'express'
export interface AuthMiddleware {
getMiddleware (): Router;
}

View file

@ -0,0 +1,96 @@
import { Router } from 'express'
import passport from 'passport'
import LDAPStrategy from 'passport-ldapauth'
import { config } from '../../../config'
import { errors } from '../../../errors'
import { logger } from '../../../logger'
import { User } from '../../../models'
import { urlencodedParser } from '../../utils'
import { AuthMiddleware } from '../interface'
export const LdapMiddleware: AuthMiddleware = {
getMiddleware (): Router {
const LdapAuth = Router()
passport.use(new LDAPStrategy({
server: {
url: config.ldap.url || null,
bindDN: config.ldap.bindDn || null,
bindCredentials: config.ldap.bindCredentials || null,
searchBase: config.ldap.searchBase || null,
searchFilter: config.ldap.searchFilter || null,
searchAttributes: config.ldap.searchAttributes || null,
tlsOptions: config.ldap.tlsOptions || null,
starttls: config.ldap.starttls || null
}
}, function (user, done) {
let uuid = user.uidNumber || user.uid || user.sAMAccountName || undefined
if (config.ldap.useridField && user[config.ldap.useridField]) {
uuid = user[config.ldap.useridField]
}
if (typeof uuid === 'undefined') {
throw new Error('Could not determine UUID for LDAP user. Check that ' +
'either uidNumber, uid or sAMAccountName is set in your LDAP directory ' +
'or use another unique attribute and configure it using the ' +
'"useridField" option in ldap settings.')
}
let username = uuid
if (config.ldap.usernameField && user[config.ldap.usernameField]) {
username = user[config.ldap.usernameField]
}
const profile = {
id: 'LDAP-' + uuid,
username: username,
displayName: user.displayName,
emails: user.mail ? Array.isArray(user.mail) ? user.mail : [user.mail] : [],
avatarUrl: null,
profileUrl: null,
provider: 'ldap'
}
const stringifiedProfile = JSON.stringify(profile)
User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile
}
}).then(function ([user, _]) {
if (user) {
let needSave = false
if (user.profile !== stringifiedProfile) {
user.profile = stringifiedProfile
needSave = true
}
if (needSave) {
user.save().then(function () {
logger.debug(`user login: ${user.id}`)
return done(null, user)
})
} else {
logger.debug(`user login: ${user.id}`)
return done(null, user)
}
}
}).catch(function (err) {
logger.error('ldap auth failed: ' + err)
return done(err, null)
})
}))
LdapAuth.post('/auth/ldap', urlencodedParser, function (req, res, next) {
if (!req.body.username || !req.body.password) return errors.errorBadRequest(res)
passport.authenticate('ldapauth', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/',
failureFlash: true
})(req, res, next)
})
return LdapAuth
}
}

View file

@ -0,0 +1,36 @@
import { Router } from 'express'
import passport from 'passport'
import { OAuth2CustomStrategy } from './oauth2-custom-strategy'
import { config } from '../../../config'
import { passportGeneralCallback } from '../utils'
import { AuthMiddleware } from '../interface'
export const OAuth2Middleware: AuthMiddleware = {
getMiddleware (): Router {
const OAuth2Auth = Router()
passport.use(new OAuth2CustomStrategy({
authorizationURL: config.oauth2.authorizationURL,
tokenURL: config.oauth2.tokenURL,
clientID: config.oauth2.clientID,
clientSecret: config.oauth2.clientSecret,
callbackURL: config.serverURL + '/auth/oauth2/callback',
userProfileURL: config.oauth2.userProfileURL,
scope: config.oauth2.scope,
state: true
}, passportGeneralCallback))
OAuth2Auth.get('/auth/oauth2', passport.authenticate('oauth2'))
// github auth callback
OAuth2Auth.get('/auth/oauth2/callback',
passport.authenticate('oauth2', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
return OAuth2Auth
}
}

View file

@ -0,0 +1,84 @@
import { InternalOAuthError, Strategy as OAuth2Strategy } from 'passport-oauth2'
import { config } from '../../../config'
import { PassportProfile, ProviderEnum } from '../utils'
import { logger } from '../../../logger'
function extractProfileAttribute (data, path: string): string {
// can handle stuff like `attrs[0].name`
const pathArray = path.split('.')
for (const segment of pathArray) {
const regex = /([\d\w]+)\[(.*)\]/
const m = regex.exec(segment)
data = m ? data[m[1]][m[2]] : data[segment]
}
return data
}
function parseProfile (data): Partial<PassportProfile> {
const username = extractProfileAttribute(data, config.oauth2.userProfileUsernameAttr)
let displayName: string | undefined
try {
// This may fail if the config.oauth2.userProfileDisplayNameAttr is undefined,
// or it is foo.bar and data["foo"] is undefined.
displayName = extractProfileAttribute(data, config.oauth2.userProfileDisplayNameAttr)
} catch (e) {
displayName = undefined
logger.debug('\'id_token[%s]\' is undefined. Setting \'displayName\' to \'undefined\'.\n%s', config.oauth2.userProfileDisplayNameAttr, e.message)
}
const emails: string[] = []
try {
const email = extractProfileAttribute(data, config.oauth2.userProfileEmailAttr)
if (email !== undefined) {
emails.push(email)
} else {
logger.debug('\'id_token[%s]\' is undefined. Setting \'emails\' to [].', config.oauth2.userProfileEmailAttr)
}
} catch (e) {
logger.debug('\'id_token[%s]\' is undefined. Setting \'emails\' to [].\n%s', config.oauth2.userProfileEmailAttr, e.message)
}
return {
id: username,
username: username,
displayName: displayName,
emails: emails
}
}
class OAuth2CustomStrategy extends OAuth2Strategy {
private readonly _userProfileURL: string;
constructor (options, verify) {
options.customHeaders = options.customHeaders || {}
super(options, verify)
this.name = 'oauth2'
this._userProfileURL = options.userProfileURL
this._oauth2.useAuthorizationHeaderforGET(true)
}
userProfile (accessToken, done): void {
this._oauth2.get(this._userProfileURL, accessToken, function (err, body, _) {
let json
if (err) {
return done(new InternalOAuthError('Failed to fetch user profile', err))
}
try {
if (body !== undefined) {
json = JSON.parse(body.toString())
}
} catch (ex) {
return done(new Error('Failed to parse user profile'))
}
const profile = parseProfile(json)
profile.provider = ProviderEnum.oauth2
done(null, profile)
})
}
}
export { OAuth2CustomStrategy }

View file

@ -0,0 +1,59 @@
import { Router } from 'express'
import passport from 'passport'
import * as OpenID from '@passport-next/passport-openid'
import { config } from '../../../config'
import { User } from '../../../models'
import { logger } from '../../../logger'
import { urlencodedParser } from '../../utils'
import { AuthMiddleware } from '../interface'
const openIDAuth = Router()
export const OPenIDMiddleware: AuthMiddleware = {
getMiddleware (): Router {
passport.use(new OpenID.Strategy({
returnURL: config.serverURL + '/auth/openid/callback',
realm: config.serverURL,
profile: true
}, function (openid, profile, done) {
const stringifiedProfile = JSON.stringify(profile)
User.findOrCreate({
where: {
profileid: openid
},
defaults: {
profile: stringifiedProfile
}
}).then(function ([user, _]) {
if (user) {
let needSave = false
if (user.profile !== stringifiedProfile) {
user.profile = stringifiedProfile
needSave = true
}
if (needSave) {
user.save().then(function () {
logger.debug(`user login: ${user.id}`)
return done(null, user)
})
} else {
logger.debug(`user login: ${user.id}`)
return done(null, user)
}
}
}).catch(function (err) {
logger.error('auth callback failed: ' + err)
return done(err, null)
})
}))
openIDAuth.post('/auth/openid', urlencodedParser, function (req, res, next) {
passport.authenticate('openid')(req, res, next)
})
openIDAuth.get('/auth/openid/callback',
passport.authenticate('openid', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
return openIDAuth
}
}

View file

@ -0,0 +1,107 @@
import { Router } from 'express'
import passport from 'passport'
import { Strategy as SamlStrategy } from 'passport-saml'
import fs from 'fs'
import { config } from '../../../config'
import { User } from '../../../models'
import { logger } from '../../../logger'
import { urlencodedParser } from '../../utils'
import { AuthMiddleware } from '../interface'
function intersection<T> (array1: T[], array2: T[]): T[] {
return array1.filter((n) => array2.includes(n))
}
export const SamlMiddleware: AuthMiddleware = {
getMiddleware (): Router {
const SamlAuth = Router()
const samlStrategy = new SamlStrategy({
callbackUrl: config.serverURL + '/auth/saml/callback',
entryPoint: config.saml.idpSsoUrl,
issuer: config.saml.issuer || config.serverURL,
cert: fs.readFileSync(config.saml.idpCert, 'utf-8'),
identifierFormat: config.saml.identifierFormat,
disableRequestedAuthnContext: config.saml.disableRequestedAuthnContext
}, function (user, done) {
// check authorization if needed
if (config.saml.externalGroups && config.saml.groupAttribute) {
const externalGroups: string[] = intersection(config.saml.externalGroups, user[config.saml.groupAttribute])
if (externalGroups.length > 0) {
logger.error('saml permission denied: ' + externalGroups.join(', '))
return done('Permission denied', null)
}
}
if (config.saml.requiredGroups && config.saml.groupAttribute) {
if (intersection(config.saml.requiredGroups, user[config.saml.groupAttribute]).length === 0) {
logger.error('saml permission denied')
return done('Permission denied', null)
}
}
// user creation
const uuid = user[config.saml.attribute.id] || user.nameID
const profile = {
provider: 'saml',
id: 'SAML-' + uuid,
username: user[config.saml.attribute.username] || user.nameID,
emails: user[config.saml.attribute.email] ? [user[config.saml.attribute.email]] : []
}
if (profile.emails.length === 0 && config.saml.identifierFormat === 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress') {
profile.emails.push(user.nameID)
}
const stringifiedProfile = JSON.stringify(profile)
User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile
}
}).then(function ([user, _]) {
if (user) {
let needSave = false
if (user.profile !== stringifiedProfile) {
user.profile = stringifiedProfile
needSave = true
}
if (needSave) {
user.save().then(function () {
logger.debug(`user login: ${user.id}`)
return done(null, user)
})
} else {
logger.debug(`user login: ${user.id}`)
return done(null, user)
}
}
}).catch(function (err) {
logger.error('saml auth failed: ' + err)
return done(err, null)
})
})
passport.use(samlStrategy)
SamlAuth.get('/auth/saml',
passport.authenticate('saml', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
SamlAuth.post('/auth/saml/callback', urlencodedParser,
passport.authenticate('saml', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
SamlAuth.get('/auth/saml/metadata', function (req, res) {
res.type('application/xml')
res.send(samlStrategy.generateServiceProviderMetadata(null))
})
return SamlAuth
}
}

View file

@ -0,0 +1,33 @@
import { Router } from 'express'
import passport from 'passport'
import { Strategy as TwitterStrategy } from 'passport-twitter'
import { config } from '../../../config'
import { passportGeneralCallback } from '../utils'
import { AuthMiddleware } from '../interface'
export const TwitterMiddleware: AuthMiddleware = {
getMiddleware (): Router {
const TwitterAuth = Router()
passport.use(new TwitterStrategy({
consumerKey: config.twitter.consumerKey,
consumerSecret: config.twitter.consumerSecret,
callbackURL: config.serverURL + '/auth/twitter/callback'
}, passportGeneralCallback))
TwitterAuth.get('/auth/twitter', function (req, res, next) {
passport.authenticate('twitter')(req, res, next)
})
// twitter auth callback
TwitterAuth.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successReturnToOrRedirect: config.serverURL + '/',
failureRedirect: config.serverURL + '/'
})
)
return TwitterAuth
}
}

View file

@ -0,0 +1,73 @@
import { Profile } from 'passport'
import { logger } from '../../logger'
import { User } from '../../models'
export function passportGeneralCallback (
accessToken: string,
refreshToken: string,
profile: Profile,
done: (err?: Error | null, user?: User) => void
): void {
const stringifiedProfile = JSON.stringify(profile)
User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile,
accessToken: accessToken,
refreshToken: refreshToken
}
}).then(function ([user, _]) {
if (user) {
let needSave = false
if (user.profile !== stringifiedProfile) {
user.profile = stringifiedProfile
needSave = true
}
if (user.accessToken !== accessToken) {
user.accessToken = accessToken
needSave = true
}
if (user.refreshToken !== refreshToken) {
user.refreshToken = refreshToken
needSave = true
}
if (needSave) {
user.save().then(function () {
logger.debug(`user login: ${user.id}`)
return done(null, user)
})
} else {
logger.debug(`user login: ${user.id}`)
return done(null, user)
}
}
}).catch(function (err) {
logger.error('auth callback failed: ' + err)
return done(err, undefined)
})
}
export enum ProviderEnum {
facebook = 'facebook',
twitter = 'twitter',
github = 'github',
gitlab = 'gitlab',
dropbox = 'dropbox',
google = 'google',
ldap = 'ldap',
oauth2 = 'oauth2',
saml = 'saml',
}
export type PassportProfile = {
id: string;
username: string;
displayName: string;
emails: string[];
avatarUrl: string;
profileUrl: string;
provider: ProviderEnum;
photos: { value: string }[];
}