refactor: auth

This commit is contained in:
wancat committed 2024-02-19 18:05:01 +08:00
1 parent d6c95cea4a
commit 5489de2432
8 files changed
+120 -22

No files matched your search

+3
View File
@@ -50,6 +50,9 @@
"@types/express-session": "^1.17.10", "@types/express-session": "^1.17.10",
"@types/jsonwebtoken": "^9.0.5", "@types/jsonwebtoken": "^9.0.5",
"@types/passport": "^1.0.16", "@types/passport": "^1.0.16",
"@types/passport-github2": "^1.2.9",
"@types/passport-jwt": "^4.0.1",
"@types/passport-local": "^1.0.38",
"@types/passport-oauth2": "^1.4.15", "@types/passport-oauth2": "^1.4.15",
"@types/validator": "^13.11.9", "@types/validator": "^13.11.9",
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
@@ -1,9 +1,16 @@
import GitHubStrategy from 'passport-github2' import { Strategy as GitHubStrategy } from 'passport-github2'
import type { Profile } from 'passport'
import type { VerifyCallback } from 'passport-oauth2'
import config from '../config.js' import config from '../config.js'
import oauthVerify from './oauthVerify.js' import oauthVerify from './oauthVerify.js'
function verify(accessToken, refreshToken, profile, cb) { function verify(
accessToken: string,
refreshToken: string,
profile: Profile,
cb: VerifyCallback
) {
oauthVerify('github', profile, { 'socialLogins.github.id': profile.id }, cb) oauthVerify('github', profile, { 'socialLogins.github.id': profile.id }, cb)
} }
@@ -1,9 +1,9 @@
import GoogleStrategy from 'passport-google-oidc' import { Strategy as GoogleStrategy } from 'passport-google-oidc'
import config from '../config.js' import config from '../config.js'
import oauthVerify from './oauthVerify.js' import oauthVerify from './oauthVerify.js'
function verify(issuer, profile, cb) { function verify(issuer: string, profile: any, cb: any) {
oauthVerify('google', profile, { 'socialLogins.google.id': profile.id }, cb) oauthVerify('google', profile, { 'socialLogins.google.id': profile.id }, cb)
} }
@@ -15,7 +15,6 @@ export default enabled
clientID: config.google.clientID, clientID: config.google.clientID,
clientSecret: config.google.clientSecret, clientSecret: config.google.clientSecret,
callbackURL: `${config.baseUrl}/api/v1/auth/google/callback`, callbackURL: `${config.baseUrl}/api/v1/auth/google/callback`,
scope: ['profile', 'email'],
}, },
verify verify
) )
@@ -1,4 +1,5 @@
import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt' import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt'
import type { VerifyCallback } from 'passport-jwt'
import config from '../config.js' import config from '../config.js'
const jwtOptions = { const jwtOptions = {
@@ -6,7 +7,7 @@ const jwtOptions = {
secretOrKey: config.secret, secretOrKey: config.secret,
} }
function verifyJwt(jwtPayload, done) { function verifyJwt(jwtPayload: any, done: VerifyCallback) {
return done(null, jwtPayload) return done(null, jwtPayload)
} }
@@ -1,11 +1,18 @@
import passport from 'passport' import passport from 'passport'
import { UserProfile } from '@linux-odyssey/models' import { UserProfile } from '@linux-odyssey/models'
import type { Express } from 'express'
import passwordStrategy from './passwordStrategy.js' import passwordStrategy from './passwordStrategy.js'
import jwtStrategy from './jwtStrategy.js' import jwtStrategy from './jwtStrategy.js'
import googleStrategy from './googleStrategy.js' import googleStrategy from './googleStrategy.js'
import githubStrategy from './githubStrategy.js' import githubStrategy from './githubStrategy.js'
import logger from '../utils/logger.js' import logger from '../utils/logger.js'
interface SerializedUser extends Express.User {
_id: string
username: string
email: string
}
passport.use(passwordStrategy) passport.use(passwordStrategy)
passport.use(jwtStrategy) passport.use(jwtStrategy)
@@ -17,32 +24,29 @@ const enabledMethods = {
logger.info('Enabled login methods', enabledMethods) logger.info('Enabled login methods', enabledMethods)
if (enabledMethods.google) { if (googleStrategy !== null) {
passport.use(googleStrategy) passport.use(googleStrategy)
} }
if (enabledMethods.github) { if (githubStrategy !== null) {
passport.use(githubStrategy) passport.use(githubStrategy)
} }
passport.serializeUser((user, done) => { passport.serializeUser((user: Express.User, done: any) => {
process.nextTick(async () => { process.nextTick(async () => {
try { try {
if (user._id && !(await UserProfile.exists({ user: user._id }))) { const serializedUser = user as SerializedUser
await UserProfile.create({ user: user._id }) if (!(await UserProfile.exists({ user: serializedUser._id }))) {
await UserProfile.create({ user: serializedUser._id })
} }
done(null, { done(null, serializedUser)
_id: user._id,
username: user.username,
email: user.email,
})
} catch (err) { } catch (err) {
done(err) done(err)
} }
}) })
}) })
passport.deserializeUser((user, done) => { passport.deserializeUser((user: SerializedUser, done) => {
process.nextTick(() => { process.nextTick(() => {
done(null, user) done(null, user)
}) })
@@ -1,8 +1,19 @@
/* eslint-disable no-unused-vars */
import bcrypt from 'bcrypt' import bcrypt from 'bcrypt'
import LocalStrategy from 'passport-local' import { Strategy as LocalStrategy } from 'passport-local'
import type { IVerifyOptions } from 'passport-local'
import type { Express } from 'express'
import { User } from '@linux-odyssey/models' import { User } from '@linux-odyssey/models'
async function verifyPassword(username, password, done) { async function verifyPassword(
username: string,
password: string,
done: (
error: any,
user?: Express.User | false,
options?: IVerifyOptions
) => void
) {
try { try {
const user = await User.findOne({ const user = await User.findOne({
$or: [{ username }, { email: username }], $or: [{ username }, { email: username }],
@@ -11,7 +22,10 @@ async function verifyPassword(username, password, done) {
return done(null, false, { message: 'Incorrect username or password.' }) return done(null, false, { message: 'Incorrect username or password.' })
} }
const isPasswordValid = await bcrypt.compare(password, user.hashedPassword) const isPasswordValid = await bcrypt.compare(
password,
user.hashedPassword || ''
)
if (!isPasswordValid) { if (!isPasswordValid) {
return done(null, false, { message: 'Incorrect username or password.' }) return done(null, false, { message: 'Incorrect username or password.' })
} }
+25
View File
@@ -0,0 +1,25 @@
/* eslint-disable no-unused-vars */
declare module 'passport-google-oidc' {
// Add specific type declarations here as needed.
// For example, if you're only using it as a middleware in Express:
import { Strategy as PassportStrategy } from 'passport'
import { Request } from 'express'
interface StrategyOptions {
clientID: string
clientSecret: string
callbackURL: string
}
interface VerifyFunction {
(
issuer: string,
profile: any,
done: (error: any, user?: any, info?: any) => void
): void
}
export class Strategy extends PassportStrategy {
constructor(options: StrategyOptions, verify: VerifyFunction)
}
}
+47 -2
View File
@@ -1493,7 +1493,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/jsonwebtoken@npm:^9.0.5": "@types/jsonwebtoken@npm:*, @types/jsonwebtoken@npm:^9.0.5":
version: 9.0.5 version: 9.0.5
resolution: "@types/jsonwebtoken@npm:9.0.5" resolution: "@types/jsonwebtoken@npm:9.0.5"
dependencies: dependencies:
@@ -1534,7 +1534,39 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/passport-oauth2@npm:^1.4.15": "@types/passport-github2@npm:^1.2.9":
version: 1.2.9
resolution: "@types/passport-github2@npm:1.2.9"
dependencies:
"@types/express": "npm:*"
"@types/passport": "npm:*"
"@types/passport-oauth2": "npm:*"
checksum: 10c0/e4e5ecd6fe16f0b18886fd259824c0f97b4c19718b67580bbe70cc7dfa858967e90d8edf602dc0b04175ce3dd8223ae103e133060df4c6cb331809ecce5fc32c
languageName: node
linkType: hard
"@types/passport-jwt@npm:^4.0.1":
version: 4.0.1
resolution: "@types/passport-jwt@npm:4.0.1"
dependencies:
"@types/jsonwebtoken": "npm:*"
"@types/passport-strategy": "npm:*"
checksum: 10c0/0ced0eaa7bb379d674821108d9bc6758223f1a5f2b9790ec78d3eaaccce6a58a424cf8ed22b53d813740ec53d929e21d92cf794ef0fb30c732866750763c0d7a
languageName: node
linkType: hard
"@types/passport-local@npm:^1.0.38":
version: 1.0.38
resolution: "@types/passport-local@npm:1.0.38"
dependencies:
"@types/express": "npm:*"
"@types/passport": "npm:*"
"@types/passport-strategy": "npm:*"
checksum: 10c0/a8464df03f073a4bb9aef7fa7cc9e76a355f149a1148330da88346d0e9c600f845601e99ed40949a13287eacae0a7ad01cd0eb5ca00d8b81da263b1dfc3aee60
languageName: node
linkType: hard
"@types/passport-oauth2@npm:*, @types/passport-oauth2@npm:^1.4.15":
version: 1.4.15 version: 1.4.15
resolution: "@types/passport-oauth2@npm:1.4.15" resolution: "@types/passport-oauth2@npm:1.4.15"
dependencies: dependencies:
@@ -1545,6 +1577,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/passport-strategy@npm:*":
version: 0.2.38
resolution: "@types/passport-strategy@npm:0.2.38"
dependencies:
"@types/express": "npm:*"
"@types/passport": "npm:*"
checksum: 10c0/d7d2b1782a0845bd8914250aa9213a23c8d9c2225db46d854b77f2bf0129a789f46d4a5e9ad336eca277fc7e0a051c0a2942da5c864e7c6710763f102d9d4295
languageName: node
linkType: hard
"@types/passport@npm:*, @types/passport@npm:^1.0.16": "@types/passport@npm:*, @types/passport@npm:^1.0.16":
version: 1.0.16 version: 1.0.16
resolution: "@types/passport@npm:1.0.16" resolution: "@types/passport@npm:1.0.16"
@@ -8492,6 +8534,9 @@ __metadata:
"@types/express-session": "npm:^1.17.10" "@types/express-session": "npm:^1.17.10"
"@types/jsonwebtoken": "npm:^9.0.5" "@types/jsonwebtoken": "npm:^9.0.5"
"@types/passport": "npm:^1.0.16" "@types/passport": "npm:^1.0.16"
"@types/passport-github2": "npm:^1.2.9"
"@types/passport-jwt": "npm:^4.0.1"
"@types/passport-local": "npm:^1.0.38"
"@types/passport-oauth2": "npm:^1.4.15" "@types/passport-oauth2": "npm:^1.4.15"
"@types/validator": "npm:^13.11.9" "@types/validator": "npm:^13.11.9"
bcrypt: "npm:^5.1.1" bcrypt: "npm:^5.1.1"